zoukankan      html  css  js  c++  java
  • setState如何同步,可以视同setTimeout(……, 0)跳出React的setState的事务控制

    参考:

    React的setState批量更新原理

    解决问题:如何让React的setState变为同步

    btnClick1

    两次同时给state.a加1.在React控制的时候,始终多次运行,只会加一次,而且因为setState不同步,console的输出始终先于setState

     btnClick1=()=>{
            this.setState({
                a: this.state.a + 1
            });
            this.setState({
                a: this.state.a + 1
            });
            console.log('点击时的a的值为:',this.state.a);
        }

    btnClick3

    两次同时给state.a加1.在React控制的时候,始终多次运行setState,会执行多次,而且因为setState跳出了Reactde异步控制,console的输出就会取到setState之后的值。

     btnClick3 = ()=>{
            setTimeout(() => {
                this.setState({
                    a: this.state.a + 1
                });
                this.setState({
                    a: this.state.a + 1
                });
                console.log('点击时的a的值',this.state.a);
            },0)
        }


    结论(React的setState批量更新原理
    异步:React 会先找到我们注册的 vnode 和 vnode 内的对应事件,从而在执行前,先把 isBatchingUpdate这个变量打开。只要我们的方法没完成,由于变量锁的存在,就会一直让我们的修改只停留在更新中状态内,一直不会更新到实际的 state
    上。直到我们的方法执行完,事务的后置函数就会关闭我们的 isBatchingUpdate,并执行渲染操作,至此整个批量更新就完成了。
    同步:setTimeout 里面会同步是由于 setTimeout会把里面的函数放到下一个宏任务内,这样就刚好跳出了事务的控制,就会显示出同步更新的情况。这里就是Javascript 的 Event-loop 机制;另外,在原生事件中,绕过了React,不会触发isBatchingUpdates变量的改变,所以也会同步进行更新渲染

    完整代码:

    菜鸟教程提供的运行环境:替换为下列代码,可以再页面和F12控制台(mac:option_command_i)查看运行结果

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8" />
    <title>菜鸟教程 React 实例</title>
    <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
    <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
    <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
    </head>
    <body>
    
    <div id="example"></div>
    <script type="text/babel">
    class App extends React.Component{
        constructor(props){
            super(props);
        }
        state = {
            a: 1
        }
        componentDidMount(){
           console.log('a的初始值为:',this.state.a);
        }
        
    
        btnClick1=()=>{
            this.setState({
                a: this.state.a + 1
            });
            this.setState({
                a: this.state.a + 1
            });
            console.log('点击时的a的值为:',this.state.a);
        }
        
        sState = ()=>{
         this.setState({
                a: this.state.a + 1
            });
        this.setState({
              a: this.state.a + 1
          });
        }
        btnClick2=()=>{
            this.sState();
            console.log('点击时的a的值为:',this.state.a);
        }
        
        btnClick3 = ()=>{
            setTimeout(() => {
                this.setState({
                    a: this.state.a + 1
                });
                this.setState({
                    a: this.state.a + 1
                });
                console.log('点击时的a的值',this.state.a);
            },0)
        }
        render(){
            return (
            <div>
                    <div>hello william</div>
                    <button onClick={this.btnClick2}>点击按钮</button>
                    <div>{this.state.a}</div>
            </div>
            )
        }
    }
    ReactDOM.render(
         <App />,
        document.getElementById('example')
    );
    </script>
    
    </body>
    </html>

    其它:React之this.setState使用需知注意点 -this.setState为什么不同步更新?

  • 相关阅读:
    第一课:js命名空间的介绍,js对象的扩展以及js数组化
    浏览器缓存机制-社招必问知识
    2013年前端校园招聘经历
    GBDT(MART) 迭代决策树简介
    coursera 公开课 文本挖掘和分析(text mining and analytics) week 1 笔记
    Predicting purchase behavior from social media-www2013
    Recommending branded products from social media -RecSys 2013-20160422
    2016年数据挖掘,机器学习可投会议
    java 中遍历hashmap 和hashset 的方法
    NLPIR分词工具的使用(java环境下)
  • 原文地址:https://www.cnblogs.com/sunupo/p/15649376.html
Copyright © 2011-2022 走看看