解读useState第二个参数的"第二个参数"

 更新时间:2024年03月13日 09:11:56   作者:Syn3ugar  
这篇文章主要介绍了useState第二个参数的"第二个参数",具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

场景引入

在学习react的过程中,为了希望能使用hook养成写函数式组件的习惯,我在完成日常作业的过程中刻意的使用hook,但也发现了几个两类组件里需要注意的问题。

先上一个需求场景:

当我们在类式组件中连续调用setState时,因为setState方法是异步的,所以即使执行到第三个setState方法时,count仍为初始值0,所以其实执行了三次setState,分别将count改为了1、2和3,但是因为最后一个方法覆盖了之前的state,所以count为3。

类式组件

参数传递回调函数

在类式组件中,如果我们希望使我们需要的三个setState方法都起我们想到的作用,最先想到的就是我们选择setState中参数的另一种传递方式——回调函数:

我们可以在此回调函数中收集到一个保存之前一次state的参数,这样虽然setState方法仍然是异步执行,但是当其执行的时候每次都能取到上一次的state并在此基础上做更新,可以达到我们想要的效果。

setState完成后执行的回调函数

另一种方式是采用setState的第二个参数——state改变后的回调函数:

这里要注意细节是不能提前解构赋值,这样只会取到第一次解构出来的初始值0。

但是这样的写法无疑是很难看的,写的多了就会形成回调地狱,使得代码可读性下降。

参数传递回调函数_promise版

为了解决回调地狱,很自然而然就想到使用promise做封装:

将按钮的回调函数变成异步函数,并把每一个setState方法用promise封装(因为await关键字只能等待promise),然后我们在state更改成功的回调里使用resolve放行,以此来模拟一个同步的场景。

函数式组件

说完了类式组件,我们调过头来使用hook来对我们的需求进行重构。

首先是使用useState的hook对组件进行重构,当然仅仅做改写肯定是没办法达到我们的需求的。

参数传递回调函数

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

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

利用useEffect监听count的变化

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

我们只好引入第二个hook:useEffect。

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

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

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

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

答案是可以!

async_await

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

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

总结

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

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

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

这些仅为个人经验,希望能给大家一个参考,也希望大家多多支持程序员之家。

相关文章

  • React中的权限组件设计问题小结

    React中的权限组件设计问题小结

    这篇文章主要介绍了React中的权限组件设计,整个过程也是遇到了很多问题,本文主要来做一下此次改造工作的总结,对React权限组件相关知识感兴趣的朋友一起看看吧
    2022-07-07
  • react 父子组件之间通讯props

    react 父子组件之间通讯props

    这篇文章主要介绍了react 父子组件之间通讯props,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • React框架快速实现简易的Markdown编辑器

    React框架快速实现简易的Markdown编辑器

    这篇文章主要为大家介绍了使用React框架实现简易的Markdown编辑器,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-04-04
  • react中使用swiper的具体方法

    react中使用swiper的具体方法

    本篇文章主要介绍了react中使用swiper的具体方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • 如何创建自己的第一个React 页面

    如何创建自己的第一个React 页面

    React是用于构建用户界面的JavaScript库,本文主要介绍了如何创建自己的第一个React页面,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • React用法之高阶组件的用法详解

    React用法之高阶组件的用法详解

    高阶组件也就是我们常说的HOC,是React中用于复用组件逻辑的一种高级技巧。这篇文章主要通过一些示例带大家学习一下高阶组件的使用,希望对大家有所帮助
    2023-04-04
  • React循环遍历渲染数组和对象元素方式

    React循环遍历渲染数组和对象元素方式

    这篇文章主要介绍了React循环遍历渲染数组和对象元素方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • React Fiber结构的创建步骤

    React Fiber结构的创建步骤

    这篇文章主要介绍了React Fiber结构的创建步骤,帮助大家更好的理解和学习使用React,感兴趣的朋友可以了解下
    2021-04-04
  • 解决React报错Rendered more hooks than during the previous render

    解决React报错Rendered more hooks than during

    这篇文章主要为大家介绍了React报错Rendered more hooks than during the previous render解决方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • 详解如何使用React和MUI创建多选Checkbox树组件

    详解如何使用React和MUI创建多选Checkbox树组件

    这篇文章主要为大家详细介绍了如何使用 React 和 MUI(Material-UI)库来创建一个多选 Checkbox 树组件,该组件可以用于展示树形结构的数据,并允许用户选择多个节点,感兴趣的可以了解下
    2024-01-01

最新评论

?


http://www.vxiaotou.com