summaryrefslogtreecommitdiff
path: root/opendc-web/opendc-web-ui/src/store/configure-store.js
diff options
context:
space:
mode:
authorFabian Mastenbroek <mail.fabianm@gmail.com>2021-05-12 22:42:12 +0200
committerFabian Mastenbroek <mail.fabianm@gmail.com>2021-05-17 17:06:47 +0200
commit4397a959e806bf476be4c81bc804616adf58b969 (patch)
treea2bfdcb314594433413a235b516d18fa5416bf6d /opendc-web/opendc-web-ui/src/store/configure-store.js
parentd21606bd238702645690586df5ad5b5075ca09c9 (diff)
ui: Migrate from CRA to Next.js
This change updates the web frontend to use Next.js instead of Create React App (CRA). Next.js enables the possibility of rendering pages on the server side (which reduces the time to first frame) and overall provides a better development experience. Future commits will try to futher optimize the implementation for Next.js.
Diffstat (limited to 'opendc-web/opendc-web-ui/src/store/configure-store.js')
-rw-r--r--opendc-web/opendc-web-ui/src/store/configure-store.js51
1 files changed, 42 insertions, 9 deletions
diff --git a/opendc-web/opendc-web-ui/src/store/configure-store.js b/opendc-web/opendc-web-ui/src/store/configure-store.js
index 13bcd69e..149536a3 100644
--- a/opendc-web/opendc-web-ui/src/store/configure-store.js
+++ b/opendc-web/opendc-web-ui/src/store/configure-store.js
@@ -1,6 +1,7 @@
+import { useMemo } from 'react'
import { applyMiddleware, compose, createStore } from 'redux'
-import persistState from 'redux-localstorage'
import { createLogger } from 'redux-logger'
+import persistState from 'redux-localstorage'
import createSagaMiddleware from 'redux-saga'
import thunk from 'redux-thunk'
import { authRedirectMiddleware } from '../auth/index'
@@ -8,20 +9,52 @@ import rootReducer from '../reducers/index'
import rootSaga from '../sagas/index'
import { viewportAdjustmentMiddleware } from './middlewares/viewport-adjustment'
-const sagaMiddleware = createSagaMiddleware()
+let store
-const middlewares = [thunk, sagaMiddleware, authRedirectMiddleware, viewportAdjustmentMiddleware]
+function initStore(initialState) {
+ const sagaMiddleware = createSagaMiddleware()
-if (process.env.NODE_ENV !== 'production') {
- middlewares.push(createLogger())
-}
+ const middlewares = [thunk, sagaMiddleware, authRedirectMiddleware, viewportAdjustmentMiddleware]
-export let store = undefined
+ if (process.env.NODE_ENV !== 'production') {
+ middlewares.push(createLogger())
+ }
-export default function configureStore() {
- const configuredStore = createStore(rootReducer, compose(persistState('auth'), applyMiddleware(...middlewares)))
+ let enhancer = applyMiddleware(...middlewares)
+
+ if (global.localStorage) {
+ enhancer = compose(persistState('auth'), enhancer)
+ }
+
+ const configuredStore = createStore(rootReducer, enhancer)
sagaMiddleware.run(rootSaga)
store = configuredStore
return configuredStore
}
+
+export const initializeStore = (preloadedState) => {
+ let _store = store ?? initStore(preloadedState)
+
+ // After navigating to a page with an initial Redux state, merge that state
+ // with the current state in the store, and create a new store
+ if (preloadedState && store) {
+ _store = initStore({
+ ...store.getState(),
+ ...preloadedState,
+ })
+ // Reset the current store
+ store = undefined
+ }
+
+ // For SSG and SSR always create a new store
+ if (typeof window === 'undefined') return _store
+ // Create the store once in the client
+ if (!store) store = _store
+
+ return _store
+}
+
+export function useStore(initialState) {
+ return useMemo(() => initializeStore(initialState), [initialState])
+}