React State & 生命周期

255 阅读1分钟

函数封装的时钟组件

Clock组件需要一个定时器每秒来更新

    function Clock(props) {
        return (
            <h2>{props.date.toLocaleTimeString()}</h2>
        )
    }
    function tick() {
        ReactDOM.render(
            <Clock date={new Date()} />,
            document.getElementById('root');
        )
    }
    setInterval(tick, 1000);

其实我们希望Clock组件做到自我更新,那么我们就用到了state这个属性,state与props类似,但是state是私有的,完全受控于当前组件。

将函数组件抓换成class组件

1.首先创建一个ES6 class继承于React.Component,然后把函数体放到一个空的render()方法中,注意render()方法中的props替换成this.props,如下:

    class Clock extends React.Component {
        render() {
            return (
                <h2>{this.props.date.toLocaleTimeString()}</h2>
            )
        }
    }

2.添加一个class构造函数,在函数中this.state赋初始值,通过super的方式将props传递到父类的构造函数中,然后在render()方法中的this.props.date替换成this.state.date,如下:

    class Clock extends React.Component {
        constructor(props) {
            super(props);
            this.state = {date:new Date()};
        }
        render(){
            return (
                <h2>{this.state.date.toLocaleTimeString()}</h2>
            )
        }
    }
    ReactDOM.render(
        <Clock />, //移除date属性
        doncument.getElementById('root')
    );

3.将生命周期方法添加到Class函数中,实现定时器:

   class Clock extends React.Component {
       constructor(props) {
           super(props);
           this.state = {date:new Date()};
       }
       componentDidMount() { //挂载函数
           this.timerID = setInterval(
               ()=> this.tick(),
               1000
           );
           //把定时器的ID保存在this.timerID
       }
       componentWillUnmount() { //卸载函数
           clearInterval(this.timerID);
       }
       tick() { //定时器方法
           this.setState({ //时刻更新组件的state
               date: new Date()
           });
       }
       render() {
           return (
               <h2>{this.state.date.toLocaleTimeString()}</h2>
           )
       }
   }
   ReactDOM.render(
       <Clock />,
       document.getElementById('root');
   );

~注意正确使用state

构造函数是唯一可以给this.state赋值的地方。不要直接修改state,this.state.date = '..'是不会渲染组件的,只有this.setState({date:'..'})才会渲染组件

考虑到性能问题,React可能会把多个setState() 调用合并成一个调用,形成一个异步更新

    //这行代码可能无法更新
    this.setState({
        counter:this.state.counter + this.props.increment
    })
    //解决这个问题需要在setState()方法里接受一个函数,这个函数用上一个state作为第一个参数,此次更新的props作为第二个参数
    this.setState((state, props) => ({
        counter: state.counter + props.increment
    }))