文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

setState的用法有哪些

2024-04-02 19:55

关注

setState的用法有哪些,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

setState是同步还是异步?

首先,这个问题的抛出,我会想为什么要抛出这个问题呢?如果说,你需要依赖状态更新后的值时,那么首先如何做呢?

首先,我们先给出结论,在React中不同的模式它的情况是不一样的,主要拿两种模式来说。

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区

  2. legacy模式

  3. concurrent模式

legacy 模式

这是当前 React app 使用的方式??

ReactDOM.render(<App />, rootNode)

当前没有计划删除本模式,但是这个模式可能不支持这些新功能。

回到我们上述的问题,setState是同步的还是异步的?

既然聊到了这里,我们来说一说batchedUpdates函数的作用。

那么它是干嘛的呢?如果你在处理逻辑函数中多次调用this.setState时,它是如何更新状态的呢?

this.setState({   value: this.state.value + 1 }) this.setState({   value: this.state.value + 1 }) this.setState({   value: this.state.value + 1 })

那React实现了这个批量更新的操作,将多次的setState合并为一次更新,那么它是如何实现的呢?batchedUpdates函数就登场了。

function batchedUpdates$1(fn, a) {     var prevExecutionContext = executionContext;     executionContext |= BatchedContext;      try {       return fn(a);     } finally {       executionContext = prevExecutionContext;        if (executionContext === NoContext) {         // Flush the immediate callbacks that were scheduled during this batch         resetRenderTimer();         flushSyncCallbackQueue(); // 同步的更新       }     }   }

这个函数会传递一个fn,当执行fn之前,会在executionContext变量上附加一个BatchedContext,当fn执行完毕后,executionContext就会把之前的BatchedContext标记给去除掉。

那么,我们是不是能够假设一下,如果在执行完fn函数后,再去更新状态的话,是不是就能完成同步的更新呢?

setTimeout函数,我们可以把setState放在定时器中,这样子一来的话,当fn函数执行完时,BatchedContext标记也去掉了,然后等到  setTimeout 的回调函数等到空闲被执行的时候,才会执行 setState。

setTimeout(() => {     this.setState({ value: this.state.value + 1})   }, 0)

这也就是当executionContext ===  NoContext,也就是会执行flushSyncCallbackQueue函数,完成此次的同步更新。

当然了,在concurrent 模式下,又是有所不同的。

这个时候,我们得谈一谈scheduleUpdateOnFiber函数。

我们都知道任务调度的起点是 scheduleUpdateOnFiber  方法,React.render、setState、forceUpdate、React Hooks 的dispatchAction 都会经过  scheduleUpdateOnFiber。

function scheduleUpdateOnFiber(fiber, lane, eventTime) {     // ...     if (root === workInProgressRoot) {       // ......      } // TO an argument to that function and this one.     if (lane === SyncLane) {  // 同步任务       if ( // 检查当前是不是在unbatchedUpdates(非批量更新),(初次渲染的ReactDOM.render就是unbatchedUpdates)       (executionContext & LegacyUnbatchedContext) !== NoContext && // Check if we're not already rendering       (executionContext & (RenderContext | CommitContext)) === NoContext) {         // Register pending interactions on the root to avoid losing traced interaction data.         schedulePendingInteractions(root, lane);          performSyncWorkOnRoot(root);       } else {         ensureRootIsScheduled(root, eventTime);         schedulePendingInteractions(root, lane);         if (executionContext === NoContext) {           resetRenderTimer();           flushSyncCallbackQueue();         }       }     } else { // 异步任务       // concurrent模式下是跳过了 flushSyncCallbackQueue 同步更新       // ....     }    }

scheduleUpdateOnFiber函数通过lane ===  SyncLane来判断是同步任务还是异步任务,我们通过ReactDom.render()方式创建的React  app是会进入这个判断的,而concurrent模式下,则不同,那么它是如何创建的呢??

concurrent 模式

你可以理解成,这个暂时还是实验阶段,当未来稳定后,将会作为React开发的默认开发模式,它是如何创建一个React App应用的呢??

ReactDOM.createRoot(rootNode).render(<App />)

这个模式开启了所有的新功能。

concurrent模式下状态的更新都是异步的。

关于React的concurrent 模式解读,有兴趣可以看看官方文档。

到这里的话,似乎我们对React中setState是同步的还是异步的就有所了解了。

关于setState的用法有哪些问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网行业资讯频道了解更多相关知识。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯