概述
引言
setState 并不是单纯同步/异步的,它的表现会因调用场景的不同而不同。在源码中,通过 isBatchingUpdates 来判断setState 是先存进 state 队列还是直接更新,如果值为 true 则执行异步操作,为 false 则直接更新。
- 异步: 在 React 可以控制的地方,如在 React 生命周期事件、合成事件中,都会走合并操作,延迟更新的策略。
- 同步: 在 React 无法控制的地方,如原生事件: addEventListener 、setTimeout、setInterval 等中,就同步更新。
有人就会问:为什么要异步?直接同步不更方便吗?
那 js 为啥需要事件循环机制呢?做异步设计是为了性能优化、减少渲染次数。React 事件处理程序中的多次 setState 的状态修改合并成一次状态修改。 最终更新只产生一次组件及其子组件的重新渲染,这对于大型应用程序中的性能提升至关重要。
示例
setstate在存储/改变值的时候是异步的,简而言之就是不会立马生效:
const [kind, setKind] = useState<any>([]);
const getSelect = () => {
axios.get(`${rmpServiceHost}/package/search_conditions`).then((res) => {
console.log(kind)
setKindList(res?.data.package_kind);
console.log(kind)
});
};
useEffect(() => {
getSelect()
getPage(kind)
}
可以发现上述代码的俩个打印结果都为空。
有一种场景,比如在第一次进入页面时,我们需要 getSelect 请求数据拿到数据 kind,并且立马就要用该数据作为参数,传给下一个请求函数 getPage 用,获取页面数据做页面呈现。
如果说像上述代码,就会出现第一次进入页面时,页面没有数据。
解决方案:async functions in useEffect
const getSelect = async () => {
const res = await axios.get(`${rmpServiceHost}/package/search_conditions`);
setKindList(res?.data.package_kind); // 这里可以不要
return res?.data.package_kind;
};
useEffect(() => {
const ok = async () => {
const kind = await getSelect()
getPage(kind);
}
ok()
}
//
若觉得ok函数多余,可以写成立即执行函数
(async () => {
const kind = await getSelect()
getPage(kind);
})()
参考链接:How to use async functions in useEffect (with examples) - Devtrium
当然也有其他方法,后续补充。
setState的参数
setState()用于设置状态对象,其语法如下:
setState(nextState,[function callback])
// nextState,将要设置的新状态,该状态会和当前的state合并
// callback,可选参数,回调函数。该函数会在setState设置成功,且组件重新渲染后调用。
setState() 的第二个参数是一个可选的回调函数,在组件重新渲染后执行。等价于在 componentDidUpdate 生命周期内执行,在这个回调函数中你可以拿到更新后 state 的值。
state和props
- state 是在组件中创建的,一般在 constructor中初始化 state。state 是多变的、可以修改,每次setState都异步更新的。
- props 是传递给组件的(类似于函数的形参),而state 是在组件内被组件自己管理的(类似于在一个函数内声明的变量)。
- props 是不可修改的,所有 React 组件都必须像纯函数一样保护它们的 props 不被更改。
最后
以上就是迷路百褶裙为你收集整理的解决setstate数据延迟问题引言 示例 setState的参数state和props的全部内容,希望文章能够帮你解决解决setstate数据延迟问题引言 示例 setState的参数state和props所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复