From 4397a959e806bf476be4c81bc804616adf58b969 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 12 May 2021 22:42:12 +0200 Subject: 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. --- .../opendc-web-ui/src/store/configure-store.js | 51 ++++++++++++++++++---- 1 file changed, 42 insertions(+), 9 deletions(-) (limited to 'opendc-web/opendc-web-ui/src/store') 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]) +} -- cgit v1.2.3