• setState的理解和用法


    1.setState更新状态的两种写法:

     (1). setState(stateChange, [callback])------对象式的setState
                1.stateChange为状态改变对象(该对象可以体现出状态的更改)
                2.callback是可选的回调函数, 它在状态更新完毕、界面也更新后(render调用后)才被调用
                        
        (2). setState(updater, [callback])------函数式的setState
                1.updater为返回stateChange对象的函数。
                2.updater可以接收到state和props。
                4.callback是可选的回调函数, 它在状态更新、界面也更新后(render调用后)才被调用。
    总结:
            1.对象式的setState是函数式的setState的简写方式(语法糖)
            2.使用原则:
                    (1).如果新状态不依赖于原状态 ===> 使用对象方式 例如:
                        this.setState({msg:"我是修改后的值"})
                    (2).如果新状态依赖于原状态 ===> 使用函数方式
                          this.setState(state => ({count:state.count+1}))
                    (3).如果需要在setState()执行后获取最新的状态数据, 
                        要在第二个callback函数中读取

    2.setState 是同步更新还是异步更新

    setState 并不是单纯同步/异步的,它的表现会因调用的场景不同而不同:在React钩子函数及合成事件中,它表现为异步;而在setTimeOut,setInterval等函数中,包括在DOM原生事件中,它都表现为同步。这种差异,本质上是由React事务机制和批量更新机制的工作方式来决定的。

     

    在源码中通过isBatchingUpdates 来判断setState是先存进state队列还是直接更新,如果值为true则执行异步操作,为false则直接更新。

    那什么情况下 isBatchingUpdates 会为 true 呢?

    · 在 React 可以控制的地方,isBatchingUpdates就为 true,比如在 React 生命周期事件和合成事件中,都会走合并操作,延迟更新的策略。

    · 在 React 无法控制的地方,比如原生事件,具体就是在 addEventListener 、setTimeout、setInterval 等事件中,就只能同步更新。

     

    一般认为,做异步设计是为了性能优化、减少渲染次数,React 团队还补充了两点:

    · 保持内部一致性。如果将 state 改为同步更新,那尽管 state 的更新是同步的,但是 props不是。 · 启用并发更新,完成异步渲染。

     

    3.如何将同步获取setState处理过后的值呢?

    1)可以在回调函数中获取setState处理过后的值。

     add = ()=>{
            // this.setState(state => ({count:state.count+1}))
            this.setState((preState)=>{
                return {count:++preState.count}
            },()=>{//此时setState异步执行
                console.log(this.state.count)//1
            })
        }

    2) 可以使用es6中的async await 来实现同步。

     add = async ()=>{
            await this.setState(state => ({count:state.count+1}))
            console.log(this.state.count)//1
        }

    3)可以使用setTimeout、setInterval

     add =  ()=>{
            setTimeout(()=>{
                this.setState(state => ({count:state.count+1}))
                console.log(this.state.count)//1
            },0)
        }

    注意:如果强行使用同步,就会每次改变状态都会重新render渲染,这样性能就会降低。

     

    不停学习,热爱是源源不断的动力。
  • 相关阅读:
    DB2常用命令2
    主流数据库命令的区别
    数据库开发
    DB2常用函数
    java Http post请求发送json字符串
    Spring Boot集成MyBatis与分页插件
    js实现加密(?!)
    本周、本月等日期的获取
    POST请求中参数以form data和request payload形式+清空数组方式
    转:目前为止最全的微信小程序项目实例
  • 原文地址:https://www.cnblogs.com/ximenchuifa/p/15066883.html
Copyright © 2020-2023  润新知