React组件编写思绪(一)

新手写 React 组件每每无从入手,怎样写,什么时候用 props,什么时候用 state 摸不着头脑。实际上是没有相识到 React 的一些头脑。就我个人的履历大多数的组件都有肯定的套路可言,接下来就先引见下 React 组件的基本头脑。

React 组件能够分为可控组件和非可控组件。可控组件意义是组件自身控制自身的状况(属性),能够经由过程自身供应的要领(供挪用者运用)来转变自身的状况。比如一个 input text 输入框供应一个 reset 要领,假如要清空用户输入则经由过程取得 inupt 组件对象,然后挪用 reset 要领来做

refs.inputRef.rest() 。

非可控组件的意义是组件自身的状况(属性)自身没法变动,只能跟着外部传入的值(props)而变化。照样拿输入框清空这一个操纵来讲,非可控的 input 不经由过程自身供应要领来转变(保护)自身的状况(value),只经由过程外部传入一个值为空字符串的 value 来做到清空的结果。

reset(){
  this.setState({
    inputValue: ''
  })
}
render(){
  return <input value={this.state.inputValue}/>
}

我们拿一个场景来看下完全的代码(一个 form 中有一个 input,有一个 reset 按妞,点击 reset 按妞会清空用户的输入),看下这两种组件誊写的区分。
受控组件例:

class App extends React.Component {
  reset = ()=>{
    this.refs.myInput.reset() // 假定 input 有一个 reset 要领
  }
  render() {
    <div>
      <form>
        <input type="text"  ref="myInput" />
        <button onClick={ this.reset }>Reset</button>
      </form>
    </div>
  }
}

非受控组件例:

class App extends React.Component {
  constructor( props ){
    super( props );
    this.state = {
      inputValue: 'Plz input your text.'
    }
  }
  reset = ()=>{
    this.setState( {
      inputValue: ''
    } )
  }
  render() {
    <div>
      <form ref="myForm">
        <input type="text" value={ this.state.inputValue }/>
        <button onClick={ this.reset }>Reset</button>
      </form>
    </div>
  }
}

接下来我们来看下假如编写这两种组件,打个比如我们要自定义一个 alert 组件。我们先从非受控组件提及,因为较简朴。非受控组件所要做的就是把一切状况提取到组件的 props 中去,render 中就用 props。一个 alert 有哪些最基本的状况(属性)呢?我们以最基本的功用定出一个示意显现与否的 show,一个示意显现内容的 content。那末组件代码以下。

class Alert extends React.Component {
  constructor( props ) {
    super( props )
  }
  render() {
    let style = {
      display: this.props.show ? 'fixed' : 'none'
    }
    return (
      <div class="my-alert" style={ style } >
        <div class="my-alert-tit">Alert</div>
        <div>{ this.props.content }</div>
        <div class="my-alert-footer">
          <button>肯定</button>
        </div>
      </div>
    );
  }
}

Alert.propTypes = {
  show: React.PropTypes.bool,
  content: React.PropTypes.string
}

我们看到最直观的就是只须要考虑到 props 的能够取值就行,不须要体贴怎样转变props。而运用这个非可控 alert 的代码以下:

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

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

接下来我们看下可控组件的alert怎样写。可控组件经由过程要领来供挪用者来转变组件的状况(属性)。所以临时我们不定义 props 只定义几个要领 show(content), hide()。组件代码以下:

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>
    );
  }
}

我们看到可控组件内部须要用到 state 来自身转变自身的状况。运用这个可控 alert 的代码以下:

import { Alert } from 'Alert';

class App extends React.Component {
  constructor() {
    super();
    this.saveHandler = ()=>{
      // ajax success
      this.refs.myAlert.show( 'Save Successfully' );
    }
  }

  render() {
    <div>
      <button onClick={ this.saveHandler }>Save</button>
      <Alert ref="myAlert"/>
    </div>
  }
}

然则可控组件有一个题目就是他的初始化状况怎样设置(怎样由外部定义组件 state 的初始化值)?因为没有 props 那末只能经由过程要领来设置,那末这么做法很别扭。这时候能够经由过程定义 props 把初始化状况在天生这个组件时传入,而没必要等组件天生完再经由过程挪用要领传入。因而修改后的代码以下:

class Alert extends React.Component {
  constructor( props ) {
    super( props )
    this.state = {
      content: this.props.defaultContent,
      show: this.props.defaultShow
    }
    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>
    );
  }
}

Alert.propTypes = {
  defaultShow: React.PropTypes.bool,
  defaultContent: React.PropTypes.string
}

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

运用这个组件的代码:

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      alertMsg: '',
      showAlert: false
    }
    this.saveHandler = ()=>{
      // ajax success
      this.refs.myAlert.show( 'Save Successfully' );
    }
  }

  render() {
    <div>
      <button onClick={ this.saveHandler }>Save</button>
      <Alert ref="myAlert" defaultShow={false} defaultContent={''}/>
    </div>
  }
}

以上就是两种 React 组件的编写思绪,你能够挑选把你的组件编写成恣意一种,那末运用者运用时也会有所不同。然则作为一个具有优越可用性的组件,不应该限定运用者的用法,那末下篇将引见怎样编写一个既能够作为可控组件,也能够作为一个非可控组件的组件写法。

    原文作者:Bernie维尼
    原文地址: https://segmentfault.com/a/1190000009389044
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞