跳至主要內容

useState,setState后立即使用state

Mr.Dylin...大约 3 分钟6.react

react class写法

在react class写法里,setState后立即使用state或者更改state,我们一般用两种写法:

1,参数传递回调函数

1700029872970
1700029872970

2,采用setState的第二个参数——state改变后的回调函数(这是最常用的方法)

1700029953420
1700029953420

react hooks

react hooks里setState没有第二个参数,所以不能使用回调;所以我列出两种实现方法

  1. react hooks 可以使用useEffect的方式,监听state的变化,state变化后就立即执行
  2. 利用异步,promise ,setTimeout,async/await来实现;例如:
    function displayModeChange (value) {
        setDisplayMode(value)
        setTimeout(() => {
          tableProps.onChange(tableProps.pagination);
        }, 0);
      }
    
下面我将详细讲述上面两种方式:

参数传递回调函数

于是立马使用useState的第二个参数,也就是操作数组的方法,将其写为一个回调函数,目的和类式组件一致,是为了拿到前一次的state:

1700030580310 那我们仍然很自然的就想复刻类式组件中setState的第二个参数——也就是传递一个state成功修改的回调函数的方法,这样我们的分享也可以到此结束了。 利用useEffect监听count的变化

可惜useState中提供的修改state的方法并没有提供这个回调函数,意味着useState的第二个参数并没有这么个“第二个参数”。

我们只好引入第二个hook:useEffect。 1700030702962 useEffect和类式组件中的生命周期有关系但并非完全有关系,我们时常通过监听一个空数组来模拟componnetDidMount生命周期,这里我们直接对count数据进行监听(类似vue中的watcher方法)。

当我们监控到了count的改变后重新调用按钮点击回调事件,但是这也容易造成死循环:回调函数改变数据,数据修改再次调用回调。

所以我们要设置好跳出条件,我们为了实现+1+2+3的方法甚至不惜再使用一个useState,其实写到这里我们已经觉得就实现这个需求而言已经不是一个很好的方法了。

那我们是不是可以再用promise进行包装呢?

答案是可以! async_await

1700030719983 这一块其实是绕了一些弯子的,我们用promise进行一层包装后,发现没有第二个参数供我们调用resolve,于是我们想到把resolve抛出,当监听到count的变化的时候再执行resolve放行,同时把监听到的count作为参数传给下一个then方法,这个then方法再次返回一个新的promise并抛出一个新的resolve,当然我们最后也可以打印一下函数看看我们绑定在函数上的这两个resolve方法。

当然还是不建议这么去做的,很明显我们这种思路更多是为了强行去利用同步思想,在此作为一种思路扩展。 总结

此处再提出一些思路供大家思考:

1、能否用setTimeout等方法包裹一下setState执行顺序呢?本质思路其实是异步任务的执行顺序层次的思考了。

2、能否手写一个带回调函数的useState呢?可以借助useRef。

上次编辑于:
贡献者: zddbic