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

React 18.2.0中Redux异步预加载状态配置问题及顶层await咨询

问题解答

1. React 18.2.0是否支持顶层await?

React 18.2.0本身不限制顶层await的使用——顶层await是ES模块(ESM)的标准特性,和React版本没有直接关联。能不能用顶层await,取决于你的项目打包工具(比如你用的Webpack)是否配置为支持ES模块,并且开启了顶层await功能。你现在遇到的Webpack配置问题,是打包工具层面的限制,不是React的问题。

2. 异步获取preloadedState的替代方案

直接把异步函数传给preloadedState不行,因为它需要的是同步的初始状态值,而不是Promise。这里有几个可行的替代方案:

方案一:在应用启动前先获取数据,再初始化store和渲染App

修改你的入口文件(比如index.js),先异步获取初始状态,再创建store并渲染React应用:

import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import { configureStore } from '@reduxjs/toolkit';
import App from './App';
import { selectionStateSliceReducer, externalTimingsReducer } from './reducers';

async function initApp() {
  // 先获取异步数据
  const selectionState = await window.browser.storage.local.get("selectionState");
  const externalTimings = await window.browser.storage.local.get("externalTimings");
  
  // 用获取到的数据创建store
  const store = configureStore({
    preloadedState: {
      selectionState,
      externalTimings
    },
    reducer: {
      selectionState: selectionStateSliceReducer,
      externalTimings: externalTimingsReducer,
    },
  });

  // 渲染应用
  const root = ReactDOM.createRoot(document.getElementById('root'));
  root.render(
    <React.StrictMode>
      <Provider store={store}>
        <App />
      </Provider>
    </React.StrictMode>
  );
}

initApp();

方案二:先创建空store,再通过dispatch初始化状态

先创建不带preloadedState的store,之后在入口文件或者根组件里,异步获取数据后dispatch对应的初始化action:

// store.js
export const store = configureStore({
  reducer: {
    selectionState: selectionStateSliceReducer,
    externalTimings: externalTimingsReducer,
  },
});

// 示例:在selectionStateSlice中定义初始化action
// import { createAction, createReducer } from '@reduxjs/toolkit';
// export const initSelectionState = createAction('selectionState/init');
// export const selectionStateSliceReducer = createReducer({}, (builder) => {
//   builder.addCase(initSelectionState, (state, action) => {
//     return action.payload;
//   });
// });

然后在入口文件或者根组件中:

import { store } from './store';
import { initSelectionState, initExternalTimings } from './slices';

async function loadInitialState() {
  const selectionState = await window.browser.storage.local.get("selectionState");
  const externalTimings = await window.browser.storage.local.get("externalTimings");
  
  store.dispatch(initSelectionState(selectionState));
  store.dispatch(initExternalTimings(externalTimings));
}

// 启动应用时调用
loadInitialState();

方案三:在根组件中用useEffect加载初始状态

如果不想阻塞应用渲染,可以先渲染应用,然后在根组件的useEffect里异步获取数据并更新store:

import { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { initSelectionState, initExternalTimings } from './slices';

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

  useEffect(() => {
    async function loadState() {
      const selectionState = await window.browser.storage.local.get("selectionState");
      const externalTimings = await window.browser.storage.local.get("externalTimings");
      
      dispatch(initSelectionState(selectionState));
      dispatch(initExternalTimings(externalTimings));
    }

    loadState();
  }, [dispatch]);

  return <div>你的应用内容</div>;
}

这种方式的好处是不会阻塞应用渲染,用户能先看到加载状态或者默认UI,等数据获取完成后再更新页面。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 16:51:36