React setState异步原理是什么
本文小编为大家详细介绍“React setState异步原理是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“React setState异步原理是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。
setState异步更新
开发中当组件中的状态发生了变化,页面并不会重新渲染。我们必须要通过setState来告知React数据已经发生了变化,重新渲染页面。
先来看下面的例子:
constructor() { super(); this.state = { message: "Hello World", };}changeText() { this.setState({ message: "Hello React", }); console.log(this.state.message); // Hello World}
最终打印的结果是Hello World;
可见setState是异步的操作,我们并不能在执行完setState之后立马拿到最新的state的结果
那么为什么setState设计为异步呢?
setState设计为异步,可以显著的提升性能
如果每次调用setState都进行一次更新,那么意味着render函数会被频繁调用,界面重新渲染,这样效率是很低的;
最好的办法是获取多个更新,之后进行批量处理;
如果同步更新了state,但是还没有执行render函数,那么state和props不能保持同步;
state和props不能保持一致性,会在开发中产生很多的问题;(比如,组件嵌套时影响子组件中的状态)
如何获取异步的结果
setState的回调
setState接受两个参数:第二个参数是一个回调函数,这个回调函数会在更新后会执行;
changeText() { this.setState({ message: "Hello React", },()=>{ console.log('-----',this.state.message); // Hello React }); }
也可以在生命周期函数中获取:
componentDidUpdate(prevProps, prevState, snapshot){ console.log(this.state.message);// Hello React }
setState一定是异步的吗?
React18版本之前
其实可以分成两种情况:
在组件生命周期或React合成事件中,setState是异步的;
在setTimeout或者原生DOM事件中,setState是同步的
验证一:在setTimeout中的更新:
setTimeout(() => { this.setState({ message: "Hello React", }); console.log(this.state.message); // Hello React }, 0);
验证二:原生DOM事件:
componentDidMount() { const btnEl = document.querySelector("#btn"); btnEl.addEventListener("click", () => { this.setState({ message: "Hello React", }); console.log(this.state.message); // Hello React }); }
React18版本之后
setState默认是异步的
在React18之后,默认所有的操作都被放到了批处理中(异步处理)
如果希望代码可以同步拿到,则需要执行特殊的flushSync操作:
import { flushSync } from "react-dom";changeText() { flushSync(() => { this.setState({ message: "Hello React", }); }); console.log(this.state.message); // Hello React }
读到这里,这篇“React setState异步原理是什么”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网行业资讯频道。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341