State & Lifecycle in React

2018-03-18  本文已影响0人  CygraWang

State

The constructor is the only place we can use this.state to initialize the state of a component.

We can then use this.setState to update the state.

When we call this.setState, React merges the object we provide into the current state, which means that the state can be updated partially.

State updates may be asynchronous, so as to update the state we can use a function (prevState, props) => ({...}) which receives two arguments, the previous state as the first argument, and the props at the time the update is applied as the second.

Lifecycle

Adding lifecycle methods to a class makes it possible to apply or free up resources taken by the components when they are rendered or destroyed. The two are called mounting and unmounting respectively in React.

We can declare special methods on the component class to run some code when a component mounts and unmounts. These methods are called lifecycle hooks.

The componentDidMount() hook runs some code after the component output has been rendered to the DOM. The code can be a timer based on setTimeout() setInterval() or a AJAX request for example.

When the component is removed from the DOM, React calls the componentWillUnmount() lifecycle hook so the code mentioned is stopped.

The whole procedure can be illustrated as:

  1. When <Compo /> is passed to ReactDOM.render(), React calls the constructor of the component. React initializes this.state with an object. We can later update this state.
  2. React then calls the component’s render() method. React then updates the DOM to match the component’s render output.
  3. When the component has been rendered in the DOM, React calls the componentDidMount() lifecycle hook. Inside it, the component asks the browser to run some code.
  4. We can use this.setState to let React know that the state has been updated. React then calls render() method again to update the DOM.
  5. If the Compo component will be removed from DOM, React calls componentWillUnmount() lifecycle hook so the text changes.
class Compo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: 'React'
    }
  }

  componentDidMount() {
    this.timer = setTimeout(
      () => this.setState({
        value: 'five seconds later'
    }), 5000)
  }

  componentWillUnmount() {
    this.setState({
      value: 'React'
    })
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.value}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Compo />,
  document.getElementById('root')
);

In addition to the two hooks mentioned, the component lifecycle also have some other methods to run code at particular times in the process.

Methods with -will- are called right before something happens.
Methods with -did- are called right after something happens.

Scene

<Input ... autoFocus={true} ... />
export default class Input extends Component {
  .
  .

  componentDidMount() {
    if (this.props.autoFocus) {
      this.textInput.focus()
      this.textInput.select()
    }
  }
  
  .
  .
  
  render(){
  ..
  }
}
  
class CompanyLogoCropper extends Component {

  state = {
    src: null,
    submitting: false,
  }

  componentWillMount() {
    const fileReader = new FileReader()
    fileReader.onload = (e) => {
      const dataURL = e.target.result
      this.setState({src: dataURL})
    }
    
  .
  .
  
  render(){
    return (
    .
    .
       <Cropper
         src={this.state.src}
         .
         .
       />
    .
    .
  }
}
    
    
componentWillReceiveProps(nextProps) {
    // content 更新后需要重新初始化以及重新求值
    if (this.props.content !== nextProps.content) {
      this.props.initializeEditorState(nextProps.content)
      if (this.props.variables && this.props.variables.length > 0) {
        this.props.evaluateVariables(this.props.variables)
      }
    }
    
    // variables 更新后需要重新求值
    if (!this.isArraysEqual(this.props.variables, nextProps.variables)) {
      if (nextProps.variables && nextProps.variables.length > 0) {
        this.props.evaluateVariables(nextProps.variables)
      }
    }
}
export default class BumenTreeSelect extends Component {
  .
  .
  componentDidUpdate() {
    $(".ant-select li").removeAttr("title")
  }
  .
  .
}
class HeadlinesPicker extends Component {
  .
  .
  componentWillUnmount() {
    window.removeEventListener('click', this.onWindowClick)
  }
  .
  .
}
class NotificationIcon extends Component {
  .
  .
  // 轮询服务器 拿到通知中心的数据
  componentDidMount() {
    let that = this
    if ( environment === 'development' ) {
      console.warn("开发环境,消息轮询已关闭")
    } else {
      this.interval = setInterval(function() {
        that.props.getNotificationInfo()
      }, 30000)
    }
  }

  componentWillUnmount() {
    clearInterval(this.interval)
  }
  .
  .
}
上一篇 下一篇

猜你喜欢

热点阅读