You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js状态管理中异步调用store方法后数据未更新问题排查

问题分析与解决:Zustand异步更新后组件拿不到最新状态

问题背景

在Next.js中使用Zustand做状态管理时,调用异步的store方法getSites并通过await等待后,在useEffect中获取的sites数据仍为空。控制台先输出in store的有效数据,再输出in useEffect的空数组,给set方法加await也无效。后来改用直接赋值this.sites = data解决了问题,但希望使用官方提供的set方法,并明确原写法出错的原因。

原代码问题原因

1. Zustand的set方法不返回Promise

你给set({ sites: data })加await没有效果,是因为Zustand的set方法不返回Promise——它是异步更新状态,但不会被await等待。因此await trackingStore.getSites()只能等待axios请求完成,无法等待store状态更新完成。

2. 直接访问store属性不是响应式快照

组件中trackingStore.sites是组件挂载时拿到的初始状态引用,即使store内部已经更新了状态,这个旧引用也不会自动更新。因为你没有用Zustand的useStore Hook订阅状态变化,useEffect的回调只会执行一次,拿到的始终是挂载时的空数组。

另外你用this.sites = data能生效,是因为这种写法直接修改了store实例的属性,但这属于不规范用法,官方推荐用set方法更新状态,避免状态更新不被追踪。

正确解决方案(使用官方set方法)

方案1:用useStore订阅状态,让组件响应更新

在组件中通过useStore订阅sites状态,状态更新时组件会自动重新渲染并拿到最新值:

import { useStore } from 'zustand';
import trackingStore from './trackingStore';

// 组件内
const sites = useStore(trackingStore, state => state.sites);
const isSitesFetching = useStore(trackingStore, state => state.isSitesFetching);

useEffect(() => {
  trackingStore.getSites();
}, []);

// 依赖sites状态,当状态更新时触发逻辑
useEffect(() => {
  if (sites?.length > 0) {
    // 处理sites数据
  }
}, [sites]);

方案2:让getSites返回数据,直接在useEffect中使用

修改store的getSites方法,返回请求到的数据,这样await后就能直接拿到最新值:

// trackingStore.js
getSites: async () => {
  set({ sites: [], isSitesFetching: true });
  const token = useAuthStore.getState().token;
  try {
    const { data } = await axios.get<Site[]>(`${apiUrl}/settings/get-sites`, {
      timeout: 90000000,
      headers: { Authorization: `Bearer ${token}` },
    });
    set({ sites: data });
    console.log('in store', data);
    return data; // 返回请求到的数据
  } catch (e) {
    console.log(e);
    return [];
  } finally {
    set({ isSitesFetching: false });
  }
},

组件中调用:

useEffect(() => {
  const fetchData = async () => {
    const sites = await trackingStore.getSites();
    console.log('in useEffect', sites);
    if (sites?.length > 0) {
      // 使用sites数据
    }
  };
  fetchData();
}, []);

这样既能遵循官方规范使用set方法更新状态,又能在useEffect中拿到最新数据,同时store状态也会同步到其他订阅的组件。

内容的提问来源于stack exchange,提问作者zzmaster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 14:32:23