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:
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.