美文网首页react
React组件编写思路(二)

React组件编写思路(二)

作者: 唯泥Bernie | 来源:发表于2017-01-23 00:35 被阅读140次

上一篇讲了 React 两种最常见的组件:受控组件和非受控组件。为了可用性,我们一般编写出来的组件希望支持这两种特性:可以通过组件自身的方法来改变组件的某(些)状态,也可以通过 props 的值的变化来改变组件自身的同一个(些)状态。

组件改变自己的状态只能通过改变 state 完成,而把 props 的变化反映到 state 却是可以通过生命周期函数来实现。首先还是拿上一篇中受控 alert 组件代码为例:

class Alert extends React.Component {
  constructor( props ) {
    super( props )
    this.state = {
      content: '',
      show: false
    }
    this.show = ( content )=>{
      this.setState( {
        content: content,
        show: true
      } )
    }

    this.hide = ()=>{
      this.setState( {
        show: false
      } )
    }
  }
  render() {
    let style = {
      display: this.state.show ? 'fixed' : 'none'
    }
    return (
      <div class="my-alert" style={ style } >
        <div class="my-alert-tit">Alert</div>
        <div>{ this.state.content }</div>
        <div class="my-alert-footer">
          <button onClick={ this.hide }>确定</button>
        </div>
      </div>
    );
  }
}

组件初始化的时候构造函数会接受传入的 props ,而当组件的容器改变传入组件的 props 的值时会触发组件的 componentWillReceiveProps 的方法,在这个方法中我们可以把变化后的 props(nextProps) 通过 setState 映射成 state 的变化。那么我们需要做的就是给受控组件增加初始化 props 处理和在 componentWillReceiveProps 内 props 的处理。

class Alert extends React.Component {
  constructor( props ) {
    super( props )
    this.state = {
      content: this.props.content || '',
      show: this.props.show || false
    }
    this.show = ( content )=>{
      this.setState( {
        content: content,
        show: true
      } )
    }

    this.hide = ()=>{
      this.setState( {
        show: false
      } )
    }
  }

  componentWillReceiveProps( nextProps ) {
    this.setState( nextProps );
  }

  render() {
    let style = {
      display: this.state.show ? 'fixed' : 'none'
    }
    return (
      <div class="my-alert" style={ style } >
        <div class="my-alert-tit">Alert</div>
        <div>{ this.state.content }</div>
        <div class="my-alert-footer">
          <button onClick={ this.hide }>确定</button>
        </div>
      </div>
    );
  }
}

那么针对同一个 alert 组件的使用就变得多样化,可以根据自己项目的需求来变化。譬如:

import { Alert } from 'Alert';

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      alertMsg: '',
      showAlert: false
    }
    this.saveHandler = ()=>{
      // save ajax success
      this.refs.myAlert.show( 'Save successfully' );
    }
    this.removeHandler = ()=>{
      // remove ajax success
      this.setState( {
        alertMsg: 'Remove successfully',
        showAlert: true
      } )
    }
  }

  render() {
    <div>
      <button onClick={ this.saveHandler }>Save</button>
      <button onClick={ this.removeHandler }>Remove</button>
      <Alert ref="myAlert" content={ this.state.alertMsg } show={ this.state.showAlert }/>
    </div>
  }
}

为了让组件更健壮,我们对 state 和 props 的一些必须的初始化值(默认值)需要明确指定

class Alert extends React.Component {
  constructor( props ) {
    super( props )
    let content = this.props.content;
    let show = this.props.show;
    /*
      props.xxx 的优先级比 props.defautXxx 高,
      如果设置了props.xxx 则 props.defaultXxx 就不起作用
    */
    this.state = {
      content: content === undefined ? this.props.defaultContent : content
      show: show === undefined ? this.props.defaultShow : show
    }
  }
}
Alert.propTypes = {
  defaultShow: React.PropTypes.bool,
  defaultContent: React.PropTypes.string,
  show: React.PropTypes.bool,
  content: React.PropTypes.string
}

Alert.defaultProps = {
  defaultShow: false,
  defaultContent: ''
}

如上代码如果对 props.xxx 和 props.defaultXxx 有迷惑的童鞋,其实有了 xxx 完全没有必要再有 defaultXxx,但是参考一些组件库的 api 设计,我理解为是为了保持受控组件 api 的统一性,如果把 alert 组件当成受控组件则初始化使用 defaultXxx,如果当成非受控组件就直接使用 xxx。

那什么时候使用受控组件,什么时候使用非受控组件呢?我们知道受控组件是比较符合我们传统 UI 组件开发的思路的。但是 React 在跨组件通讯方面很弱,如果不借助第三方库进行通讯,对于两个毫无关系的组件相互调用就需要传递层层的回调函数。我想没有人喜欢这种编程风格,所以把所有组件的状态抽象到一个地方进行集中管理变化,典型的数据流用 redux 就倾向于使用非受控组件了(这里不讨论flux思想的由来,不讨论redux好坏)。

故最基本的 React 组件编写套路就这些。但是这些还只是 api 应用层面的东西,比较难的是在编写组件时候对状态的抽象,使使用者使用的舒服自然。

相关文章

  • React组件编写思路(二)

    上一篇讲了 React 两种最常见的组件:受控组件和非受控组件。为了可用性,我们一般编写出来的组件希望支持这两种特...

  • React组件编写思路(一)

    新手写 React 组件往往无从入手,怎么写,什么时候用 props,什么时候用 state 摸不着头脑。其实是没...

  • React学习(5)-React中组件的数据-props

    前言 开发一个React应用,更多的是在编写组件,而React组件最小的单位就是React元素,编写组件的最大的好...

  • 面试题

    React组件的渲染流程是什么? 使用 React.createElement或 JSX编写 React组件,实际...

  • react组件-编写组件

    组件声明 新建组件的命首页字母要为大写,否者在引用的时候会报错,react核心会认为是一个HTML标签,并无法解析...

  • React 组件编写

    react组件有三种编写方式,这里介绍两种比较普遍流行的编写方式. 一·无状态函数定义组件 我们之所以称这种类型的...

  • React Native学习<三> ReactNative入门基

    <一>编写Hello World React Native看起来很像React,只不过其基础组件是原生组件而非we...

  • GrowingIO Design 组件库搭建之单元测试

    前言 GrowingIO Design 是用 React 编写的组件库,本质上就是 React 组件,你可以用像测...

  • NT 技术周刊-1028

    React-Native 组件开发方法[原创] 摘要 �React Native的开发思路是通过组合各种组件来组织...

  • React笔记

    1、组件如果我们使用react搭建页面的话,页面就是由我们编写的组件各种组合嵌套而来,可以说组件是react的基本...

网友评论

    本文标题:React组件编写思路(二)

    本文链接:https://www.haomeiwen.com/subject/uttabttx.html