欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > state的异步跟新

state的异步跟新

2025/1/23 6:27:54 来源:https://blog.csdn.net/m0_47999208/article/details/145310180  浏览:    关键词:state的异步跟新

预测下刷新页面后,页面上会有啥数字出现

import React, { useState, useEffect } from "react";const Bpp = () => {const [data, setData] = useState([]);// const [loading, setLoading] = useState(true);const [errorData, setErrorData] = useState([]);useEffect(() => {const newList = [];for (let i = 0; i < 1000; i++) {newList.push({name: `标题${i}`,});}setData(newList);setErrorData(data);}, []);return (<div>{data.length},{errorData.length}</div>)
}export default Bpp;

一、组件的初始化阶段

  1. 状态初始化

    • const [data, setData] = useState([]);:将 data 初始化为一个空数组。
    • const [errorData, setErrorData] = useState([]);:将 errorData 初始化为一个空数组。
  2. 首次渲染

    • 当组件首次渲染时,会执行 return 语句,显示 <div>{data.length},{errorData.length}</div>
    • 由于 data 和 errorData 都是初始状态,它们的长度都是 0,所以页面会显示 0,0

二、useEffect 的执行

  1. useEffect 触发

    • 由于 useEffect 的依赖项数组为 [],该 useEffect 只会在组件挂载后执行一次,类似于 componentDidMount 生命周期方法。
    • 当组件挂载完成后,useEffect 开始执行。
  2. useEffect 内部操作

    • 一个包含 1000 个元素的 newList 被创建:
      const newList = [];
      for (let i = 0; i < 1000; i++) {newList.push({name: `标题${i}`,});
      }
      
    • setData(newList); 被调用:
      • 这将触发 React 状态更新,把 data 状态更新为包含 1000 个元素的数组。但 React 的状态更新是异步的,意味着 data 的更新不会立即完成。React 不会立即更新 data 的值,而是会将状态更新排入队列,并在稍后进行更新
    • setErrorData(data); 被调用:
      • 由于状态更新的异步性,此时 data 仍然保持其旧值(即空数组),因为 setData 操作尚未完成更新。因此,setErrorData 会将 errorData 状态更新为一个空数组。

三、最终结果

  1. 后续渲染
    • 在 useEffect 执行之后,组件会重新渲染。
    • 此时,data 状态已经更新,因为 setData 的更新操作已经完成,所以 data.length 为 1000
    • 但是,errorData 状态仍然是空数组,因为在 useEffect 中,setErrorData 接收到的是 data 的旧值,所以 errorData.length 为 0

  • 页面上最终显示 1000,0 的原因是 useEffect 内部状态更新的顺序和异步特性。在 useEffect 中调用 setData(newList) 不会立即更新 data,而后续的 setErrorData(data) 使用的是 data 的旧值(即初始的空数组),导致 errorData 最终仍然是一个空数组,而 data 最终更新为包含 1000 个元素的数组。

解决代码

import React, { useState, useEffect } from "react";const Bpp = () => {const [data, setData] = useState([]);// const [loading, setLoading] = useState(true);const [errorData, setErrorData] = useState([]);useEffect(() => {const newList = [];for (let i = 0; i < 1000; i++) {newList.push({name: `标题${i}`,});}setData(newList);}, []);useEffect(() => {setErrorData(data);}, [data]);return (<div>{data.length},{errorData.length}</div>)
}export default Bpp;

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com