肉渣教程

生命周期

上一节 下一节

紧接上一章节示例,通过将生命周期(Lifestyle)添加到类组件来实现动态时钟组件。


生命周期(Lifestyle)

在具有很多组件的web应用中,一定要注意当组件实例被销毁时,要及时释放其所占用的资源。如下所示,在React组件生成的React元素被加载到DOM中,则会运行componentDidMount()方法(在此方法中创建计时器);当这个React元素从DOM中被移除时则会运行componentWillUnmount()方法(在此方法中销毁计时器,回收系统资源)。

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

  componentWillUnmount() {
    clearInterval(this.timerID);
  }

  tick() {
    this.setState({
      date: new Date()
    });
  }

  render() {
    return (
      <div>
         <h1>反清复明</h1>
         <p>现在时间是:{this.state.date.toLocaleTimeString()}</p>
      </div>
    );
  }
}

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

运行一下


上述过程如下所述:

  1. <Clock />即根据Clock组件生成React元素,因为需要显示当前时间,故而使用this.state来出存储时间对象;
  2. 当React组件生成的元素对象被插入到DOM中,该对象则会调用ComponentDidMount()方法,来创建一个计时器;
  3. 计时器每秒会调用一次tick()方法,该方法会通过调用setState()来计划进行一次状态更新,当元素对象的状态更新,UI则随之更新;
  4. 一旦Clock组件生成的元素对象从DOM中被移除,React就会调用componentWillUnmount()方法来移除计时器以回收系统资源。

setState() 方法

对于state状态的更新,请使用setState()方法进行更新,而不要直接修改state。(constructor(props)初始化构造函数是唯一可以直接对this.state进行赋值的地方)

// 错误,UI不会发生改变
this.state.date = new Date();

// 正确,UI会随之重新渲染
this.setState({ date: new Date() });


State的更新是异步的(this.statethis.props的更新都是异步的);因此,若要更新state,就不应直接依赖这些异步更新的对象的值,这样是不安全准确的。解决方式就是通过使用函数的方式,利用函数中局部变量的独立性,来保证state更新的安全。

// 错误,依赖了异步更新的 this.state
this.setState({
  counter: this.state.counter + 1,
});

// 正确,使用函数的方式来避免直接更新
this.setState(function(state) {
  return {
    counter: state.counter + 1
  };
});

// 同样正确,使用箭头函数来简化普通的函数
this.setState((state) => ({
  counter: state.counter + 1
}));


上面的例子中只是依赖了this.state,再举一个同时依赖了this.statethis.props的例子,函数的形参设2个即可:

// 错误,依赖了异步更新的 this.state
this.setState({
  counter: this.state.counter + this.props.increment,
});

// 正确,使用函数的方式来避免直接更新
this.setState(function(state) {
  return {
    counter: state.counter + props.increment
  };
});

// 同样正确,使用箭头函数来简化普通的函数
this.setState((state) => ({
  counter: state.counter + props.increment
}));

生命周期

上一节 下一节