React 学习笔记之状态(state)和生命周期

本文中我们同样使用 React 官方教程中的一个时钟的案例来给大家讲解 state 的作用及时生命周期中的一些接口函数。案例可能与官方不是很匹配,是因为我经过刻意修改,为的是以国人理解的方式再重新梳理一遍,让大家更容易理解。

显示一个时间

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class Clock extends Component {
  render() {
    return (
      <div>
        <h1>{new Date().toLocaleTimeString()}</h1>
      </div>
    );
  }
}

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

以上代码实现了一个 Clock 的组件,该组件很简单的在一个 h1 标签中显示了当前时间,但是你会发现这个时间是个静止的时间,很明显,它没什么实际作用,我们要想办法让它动起来。所以我们就要用到 state + 生命周期中提供的一些接口来实现这个功能。

使用 state 来显示时钟

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

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

  render() {
    return (
      <div>
        <h1>{this.state.date.toLocaleTimeString()}</h1>
      </div>
    );
  }
}

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

经过改造后,我们仅仅是在构造函数(constructor)中给 this.state 赋了一个初值。然后在 render 中显示了 this.state.date 中的内容。但同样,这个时间还是静止的,我们要想办法让它一秒变一次。那么接下来就用到了生命周期相关的接口。

使用声明周期相关接口

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

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

  // 组件已经挂载
  componentDidMount() {
    this.timerId = setInterval(
      () => this.tick(),
      1000
    );
  }

  // 组件即将被移除
  componentWillUnMount() {
    clearInterval(this.timerId);
  }

  // 每一秒设置一次 state 中 date 的值
  tick() {
    this.setState({
      date: new Date()
    });
  }

  render() {
    return (
      <div>
        <h1>{this.state.date.toLocaleTimeString()}</h1>
      </div>
    );
  }
}

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

我们增加了两个函数,一个是 componentDidMount,该函数会在组件已经加载完毕后被调用。另外一个是 componentWillUnMount,该函数会在组件即将被销毁时调用。

我们在 componentDidMount 函数中增加了一个定时器,每一秒调用一次 tick 函数,这个函数是我们新实现的,目的就是调用一下 setState 方法来设置 state 里面的值,当 state 里面的值改变时,控件上使用的 state.date.toLocaleTimeString() 的值也就会跟随变更。这样我们就实现了时间的自动更新。最后在组件即将被销毁时,我们有调用了 clearInterval 清除了定时器。最终时间就会在界面上自动变更了。

这就是 state 的作用,大家可以想一想,如果在传统 web 前端技术中,你想实现这样一个功能要如何实现呢?对比 React 有什么优势或者缺点吗?

注意事项

不可以直接修改状态

// Wrong
this.state.comment = 'Hello';

必须使用 setState 方法

// Correct
this.setState({comment: 'Hello'});

你唯一能给其赋初值的地方就是构造函数。

setState 是异步的

参考该文章:https://segmentfault.com/a/1190000007454080

评论