You might run into a situation where you want to trigger a redirect as soon as possible in case some particular piece of state is or is not set.
A possible use case could be persisting checkout state, e.g. checkoutSteps.step1Completed
.
To do this, the only method I'm aware of is using good old Cookies so we already have the state available during the server rendering cycle.
// routesMap.js
// ...
const canContinueIf = (stepCompleted, dispatch, fallbackRoute) => {
if (!stepCompleted) {
const action = redirect({ type: fallbackRoute })
dispatch(action)
}
// ...
export default {
// ...
CHECKOUT_STEP_2: {
path: '/checkout-step-2',
thunk: (dispatch, getState) => {
const { checkoutSteps } = getState()
canContinueIf(checkoutSteps.step1Completed, dispatch, 'CHECKOUT_STEP_1')
}
}
// ...
}
// server/configureStore.js
//...
const parseCookies = (cookies) => {
const parsedCookies = {}
Object.keys(cookies).forEach((key) => {
const value = cookies[key]
const decodedKey = decodeURIComponent(key)
const keyWithoutReduxPersistPrefix = decodedKey.replace(/reduxPersist:/, '')
if (key !== 'reduxPersistIndex') { // TODO: This could be expanded into a real black- or whitelist
parsedCookies[keyWithoutReduxPersistPrefix] = JSON.parse(value)
}
})
return parsedCookies
}
//...
export default async (req, res) => {
// ...
const parsedCookies = parseCookies(req.cookies)
const preLoadedState = { ...parsedCookies } // onBeforeChange will authenticate using this
// ...
}
// src/configureStore.js
//...
export default (history, preLoadedState) => {
// …
const store = createStore(rootReducer, preLoadedState, enhancers)
if (!isServer) {
persistStore(store, {
blacklist: ['location', 'page'],
storage: new CookieStorage()
})
}
// …
}
// server/index.js
import cookieParser from 'cookie-parser'
// ...
app.use(cookieParser())
// ...