异步数据需在响应完成、状态更新、组件重渲染后使用;应通过promise链、函数式setstate、useeffect监听props、context统一管理等方式确保时机正确和状态一致。

异步请求返回的数据不能直接赋值后立刻使用,因为请求还没完成,变量还是初始值。关键不是“怎么取数据”,而是“什么时候取才安全”——得等响应真正回来、状态更新完毕、组件完成重渲染之后。
用 Promise 链确保顺序执行
把后续依赖该数据的操作,明确写在 .then() 里,而不是放在请求语句后面。这样逻辑天然受控于异步完成时机。
- 错误写法:let data; uni.request({ ... }); console.log(data); // 此时 data 还是 undefined
- 正确写法:uni.request({...}).then(res => { data = res.data; doSomethingWith(data); })
- 多个请求有依赖?链式调用:.then(res1 => request2(res1.id)).then(res2 => ...)
函数组件中避免闭包 stale state
事件回调或定时器里读取的 state 可能是旧快照。不要在异步回调里直接用当前渲染周期的 state 变量。
- 问题场景:setCount(count + 1); setTimeout(() => console.log(count), 100); // 输出旧值
- 解法一(推荐):用函数式更新,让 React 自动传入最新 prev 值:setCount(prev => { console.log('最新值', prev); return prev + 1; });
- 解法二:用 useRef 同步记录最新值,异步中读 ref.current:const countRef = useRef(count); useEffect(() => { countRef.current = count; }, [count]);
子组件需要实时响应父组件异步结果
别靠 props 默认值或初始化时读一次 props,要监听变化。React 中 props 更新会触发子组件重新渲染,只要子组件用的是最新 props,就自然拿到最新值。
- 错误做法:const [localData, setLocalData] = useState(props.asyncData); // 初始化后不再更新
- 正确做法:useEffect(() => { setLocalData(props.asyncData); }, [props.asyncData]);
- 更简洁:直接在 render 中使用 {props.asyncData?.name},无需中间 state
- 复杂处理逻辑?加一层 useMemo 缓存计算结果:const processed = useMemo(() => transform(props.asyncData), [props.asyncData])
全局状态或跨层级通信时保持一致性
当多个组件共用同一份异步数据(比如用户信息),避免各自发请求或各自维护副本。
- 统一由顶层组件(如 App 或 Layout)发起请求并管理 loading / error / data 状态
- 通过 Context 提供数据和更新函数:const { user, updateUser } = useContext(UserContext)
- 配合 useReducer 或 Zustand 管理带副作用的状态流转,确保 dispatch 后所有订阅者同步收到新值










