Home > Back-end >  How to initialize globally redux store with data from server?
How to initialize globally redux store with data from server?

Time:07-16

I have the following Root reducer file:

const rootReducer = combineReducers<IAppState>({
    auth: authReducer,
    alert: alertReducer,
    trees: TreeReducer
});

let initialState = {} as IAppState;
(async () => {
    initialState = await getInitializationData();
    console.log(1)
})()
console.log(2)

export const store = configureStore({
    reducer: rootReducer,
    preloadedState: initialState
})

export type AppDispatch = typeof store.dispatch

The function getInitializationData is supposed to make an appropriate request on the server to get initial data. But it does not work. I have the following result:

enter image description here

as you can see from this screen, I'm initializing my store with an empty object because the function acts later than the configureStore.

Ok, I could use async/await top level. Relatively new feature, still experimental, but anyway. I changed my tsconfig.json to the following variant:

{
  "compilerOptions": {
    "target": "es2017",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": [
    "src",
    "declaration.d.ts"
  ]
}

Root reducer looks like:


const rootReducer = combineReducers<IAppState>({
    auth: authReducer,
    alert: alertReducer,
    trees: TreeReducer
});

const initialState = await getInitializationData();

export const store = configureStore({
    reducer: rootReducer,
    preloadedState: initialState
})

export type AppDispatch = typeof store.dispatch

But I get the following error:

ERROR in ./src/redux/RootReducer.ts
Module parse failed: The top-level-await experiment is not enabled (set experiments.topLevelAwait: true to enabled it)
File was processed with these loaders:
 * ./node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/index.js
 * ./node_modules/babel-loader/lib/index.js
 * ./node_modules/source-map-loader/dist/cjs.js
You may need an additional loader to handle the result of these loaders.
Error: The top-level-await experiment is not enabled (set experiments.topLevelAwait: true to enabled it)
    at C:\Projects\MyFamilyTree\MyFamilyTree\FrontendApp\my-family-tree\node_modules\webpack\lib\dependencies\HarmonyDetectionParserPlugin.js:54:11
    at Hook.eval [as call] (eval at create (C:\Projects\MyFamilyTree\MyFamilyTree\FrontendApp\my-family-tree\node_modules\tapable\lib\HookCodeFactory.js:19:10), <anonymous>:7:16)
    at Hook.CALL_DELEGATE [as _call] (C:\Projects\MyFamilyTree\MyFamilyTree\FrontendApp\my-family-tree\node_modules\tapable\lib\Hook.js:14:14)
    at JavascriptParser.walkAwaitExpression (C:\Projects\MyFamilyTree\MyFamilyTree\FrontendApp\my-family-tree\node_modules\webpack\lib\javascript\JavascriptParser.js:2320:29)
    at JavascriptParser.walkExpression (C:\Projects\MyFamilyTree\MyFamilyTree\FrontendApp\my-family-tree\node_modules\webpack\lib\javascript\JavascriptParser.js:2250:10)
    at JavascriptParser.walkVariableDeclaration (C:\Projects\MyFamilyTree\MyFamilyTree\FrontendApp\my-family-tree\node_modules\webpack\lib\javascript\JavascriptParser.js:2104:33)
    at JavascriptParser.walkStatement (C:\Projects\MyFamilyTree\MyFamilyTree\FrontendApp\my-family-tree\node_modules\webpack\lib\javascript\JavascriptParser.js:1598:10)
    at JavascriptParser.walkStatements (C:\Projects\MyFamilyTree\MyFamilyTree\FrontendApp\my-family-tree\node_modules\webpack\lib\javascript\JavascriptParser.js:1459:9)
    at JavascriptParser.parse (C:\Projects\MyFamilyTree\MyFamilyTree\FrontendApp\my-family-tree\node_modules\webpack\lib\javascript\JavascriptParser.js:3353:9)
    at C:\Projects\MyFamilyTree\MyFamilyTree\FrontendApp\my-family-tree\node_modules\webpack\lib\NormalModule.js:1087:26

I know I'm supposed to change my webpack config. But I do not have it! Because I use React Create App. I can't believe that CRA does not provide this simple thing like global initial state initialization from server.

CodePudding user response:

You would usually just not do that - imagine that request takes 10 seconds or fails - the user will just see a white screen in the meantime because you can't really render your application before your store exists.

Initialize your store with a sane "placeholder" value, show a "loading" screen and make a normal asynchronous request to the server - then dispatch an action to modify your existing state's contents.

  • Related