天天看点

React之setState详解

React 项目中的 UI 的改变来源于 State 改变,类组件中 setState 是更新组件,渲染视图的主要方式:

基本用法

setState(obj, callback)      

setState 的第一个参数: 当 obj 为一个对象的时候,则为即将合并的 state,如何 obj 是一个函数,那么当前组件的 state 和 props 将作为参数,返回值用于 合并新的 state。

setState 的第二个参数:当 callback 为一个函数,函数执行上下文中可以获取当前 setState 更新后的最新 state 的值,可以作为以来 state 变化的副作用函数,可以 用来做一些基本的 DOM 操作等。

// 第一个参数为function类型的时候

this.setState((state, props) => {
    return { number: 1 }
})

// 第一个参数为object类型的时候
this.setState({ number: 1 }, () => {
    console.log(this.state.number) // 获取最新的number
})      

如何监听State变化?

. 在类组件中的 state 中,有第二个 callback 或者是在生命周期的 componentDidUpdate 中可以检测监听到 state 改变或是组件更新、 b. 那么在函数组件中,如何怎么监听 state 变化呢?这时候就需要 useEffect 出场,通常可以把 state 作为依赖项传入 useEffect 第二个参数 deps,但是 注意 useEffect 初始化会默认执行一次。

export defailt function Index(props) {
    const [number,setNumber] = React.useState(0)
    React.useEffect(() => {
        console.log("监听number变化,此时的number 是"+ number)
    },[number])

    const handleClidk = () => {
        // 最高的优先级
        ReactDOM.flushSync((0 => {
            setNumber(2)
        }))

        //批量更新
        setNumber(1)

        // 稍后更新,批量更新规则被打破
        setTimeout(() => {
            setNumber(3)
        })

        console.log(number)
        return <div>
            <span>{number}</span>
            <button onClick={handleClick}>number++</button>
        </div>
    }

}      

useState 注意事项:

在使用 useState 的 dispatchAction 更新 state 的时候,记得不要传入相同的 state,这样会使试图不更新。如下面:

React之setState详解

造成这样的原因是,在 useState 的 dispatchAction 的处理逻辑中。会浅比两次的 state,发现 state 相同,就不会开启更新调度任务,demo 中两次 state 指向了相同的内存空间,所以默认 state 是相等的,就不会发生试图更新。 如要解决,则将 dispatchState 改成 dispatchState({...state}) 可以从根本解决问题。 结果就是浅拷贝对象,重新申请了一个内存空间。

useState 与 setState 有什么不同?

答:

相同点: setState 合 useState 更新视图,底层都调用了 scheduleUpdateOnFiber 方法。而且事件驱动情况下都有批量更新规则。

不同点:

继续阅读