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

如何在Redux Toolkit中异步设置preloadedState?

问题解答

首先明确:configureStore的preloadedState必须是同步值,不能传入Promise或者异步函数,所以你直接把异步的loadStateFromStorage赋值给它是行不通的。下面给你两种更优雅的实现方式:

方案一:异步获取数据后再初始化Store(优化你当前的方案)

你现在的思路是对的,只是可以把代码封装得更整洁:

1. 封装状态加载与Store创建逻辑

在store.js里统一处理:

export const loadStateFromStorage = async () => {
  const result = await window.chrome.storage.local.get(["multitask-state"]);
  return result["multitask-state"] ? JSON.parse(result["multitask-state"]) : undefined;
};

export const createStore = (preloadedState) => configureStore({
  reducer: {
    tasks: taskReducer,
    timer: timerReducer
  },
  preloadedState,
  middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat([storeStateToStorage])
});

2. 入口文件异步初始化并渲染

// index.js
import { loadStateFromStorage, createStore } from './store';

async function initApp() {
  const initialState = await loadStateFromStorage();
  const store = createStore(initialState);
  
  root.render(
    <React.StrictMode>
      <Provider store={store}>
        <App />
      </Provider>
    </React.StrictMode>
  );
}

initApp();

这种方式逻辑清晰,完全贴合Redux的初始化流程,不会产生额外的状态同步问题。

方案二:先初始化空Store,再异步加载状态(适合不想延迟渲染的场景)

如果不想让App因加载状态而延迟渲染,可以先创建无预加载状态的Store,再在App挂载后通过dispatch action加载本地存储的状态:

1. 创建基础Store并添加加载状态的action

// store.js
export const store = configureStore({
  reducer: {
    tasks: taskReducer,
    timer: timerReducer
  },
  middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat([storeStateToStorage])
});

// 定义加载tasks状态的action
export const loadTasksState = (state) => ({
  type: 'tasks/loadState',
  payload: state
});

// 在taskReducer中添加对应的处理逻辑
const taskReducer = createReducer(initialState, (builder) => {
  builder
    // 保留原有业务逻辑的case
    .addCase(loadTasksState, (state, action) => {
      // 根据需求合并或替换状态,示例为合并
      return { ...state, ...action.payload };
    });
});

// 同理可添加timer状态的加载action与reducer逻辑

2. 在App组件中异步加载并分发状态

// App.js
import { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { loadTasksState } from './store';

function App() {
  const dispatch = useDispatch();

  useEffect(() => {
    async function loadSavedState() {
      const result = await window.chrome.storage.local.get(["multitask-state"]);
      if (result["multitask-state"]) {
        const savedState = JSON.parse(result["multitask-state"]);
        dispatch(loadTasksState(savedState.tasks));
        // 若有timer状态,同步dispatch对应的加载action
      }
    }

    loadSavedState();
  }, [dispatch]);

  // 可在状态加载完成前显示加载提示
  return (
    <div className="app">
      {/* 你的组件内容 */}
    </div>
  );
}

这种方式适合需要快速渲染App、后台加载状态的场景,用户不会看到长时间白屏,但需要处理状态加载前后的UI过渡(如加载态)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 19:25:05