react - setState

2018-04-14  本文已影响21人  heheheyuanqing

之前面试的时候问到setState调用之后state值是否会立即改变,答案是否定的,借此来讲述一波自己在学习之后对 setState机制


首先由代码引入

class ComponentsetState extends Component {
    constructor() {
        super();
        this.state={
            name: "heheyuanqing",
            age: 18
        };
    }

    changeState = function () {
        this.setState({
            name: "superman",
            age: 25
        });
        console.log(this.state);
    }

    render() {

        return (
            <div className="parent">
                <div>name:{this.state.name}</div>
                <div>age:{this.state.age}</div>
                <button onClick={this.changeState.bind(this)}>修改</button>
            </div>
        )
    }

}
点击之后state的值并没有立即发生改变

接着继续看,将console输出作为setState第二个参数

 changeState = function () {
       this.setState({
            name: "superman",
            age: 25
        },function () {
            console.log(this.state);
        });
        console.log(this.state);
    }
使用setState的第二个参数

最后再看一个,使用setTimeout调用setState

changeState = function () {
        setTimeout(()=>{
            this.setState({
                name: "superwoman",
                age: 25
            });
            console.log(this.state);
        },0);
    }
setTimeout实现同步改变
调用setState之后发生的事情:

具体代码可以查看源码

首先获取组件对象;
接着查看组件的_pendingStateQueue(数组),并且将new state存入;
最后调用enqueueUpdate()

首先通过batchingStrategy.isBatchingupdates判断是否处于更新阶段
true将待更新组件存入dirtyComponent中
反之,调用batchedUpdates()

首先将isBatchingUpdates设置为true,进入更新阶段
接着以事务的形式处理:transation.perform()
*wrapper封装了两个函数:
RESET_BATCHED_UPDATES(初始化:[空函数];close:[设置isBatchingUpdates为false,更新结束]);
FLUSH_BATCHED_UPDATES(初始化:[空函数];close:[遍历dirtyComponent,执行runBatchUpdates]);

首先调用performUpdateIdNeccessary执行updateComponent,执行生命周期方法;
接着完成执行前的callback(即state中的第二个参数)

了解一下transation

通过wrapper封装方法函数,使用perform开始执行事务,首先执行所有方法的initialize的方法,然后再执行perform的callback函数,最后执行所有方法的close方法

ASCII图

在调用setState方法之后,state的值并不是立即改变的,具有延时执行的行为,是不保证同步

在shouldComponentUpdate、componentWillUpdate中调用setState时最后在updateComponent中会调用shouldComponentUpdate、componentWillUpdate造成循环调用


最后,回到代码

参考链接:
https://zhuanlan.zhihu.com/p/20328570
https://blog.csdn.net/u013510838/article/details/59486772#t0

上一篇 下一篇

猜你喜欢

热点阅读