Closed matheus-rosin closed 5 years ago
I tried something based on this and got this thing working. Here is how it looks like:
// store.js
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { createLogger } from 'redux-logger';
import rootReducer from './reducers';
import * as initialState from './initialState';
const middlewares = [thunk];
if (process.env.NODE_ENV !== 'production') {
middlewares.push(createLogger());
}
function makeConfiguredStore(reducer, initialState) {
return createStore(
reducer,
initialState,
applyMiddleware(...middlewares),
);
}
export function initializeStore(initial = initialState, isServer) {
if (isServer) {
// if is server, return just store -- not even import redux-persist stuff
return {
store: makeConfiguredStore(rootReducer, initial),
};
}
const { persistReducer, persistStore } = require('redux-persist');
const createEncryptor = require('redux-persist-transform-encrypt').default;
const storage = require('localforage');
const encryptor = createEncryptor({
secretKey: process.env.reduxPersistEncryptorSecretKey,
});
const persistedReducer = persistReducer({
key: 'some-key',
storage,
transforms: [encryptor],
blacklist: ['_persist'],
}, rootReducer);
let store = makeConfiguredStore(persistedReducer, initial);
let persistor = persistStore(store);
return { store, persistor };
}
// stateHOC.js
import { Component } from 'react';
import { initializeStore } from './store';
const isServer = typeof window === 'undefined';
const __NEXT_REDUX__ = '__NEXT_REDUX__';
function getOrCreateStore(state) {
// note line below
if (isServer) return initializeStore(state, isServer);
if (!window[__NEXT_REDUX__]) {
// note line below
window[__NEXT_REDUX__] = initializeStore(state, isServer);
}
return window[__NEXT_REDUX__];
}
export default (App) => {
return class extends Component {
static async getInitialProps(appContext) {
const { store, persistor } = getOrCreateStore();
appContext.ctx.reduxStore = store;
appContext.ctx.reduxPersistor = persistor;
let appProps = {};
if (App.getInitialProps) {
appProps = await App.getInitialProps(appContext);
}
return {
...appProps,
initialState: store.getState(),
};
}
constructor(props) {
super(props);
let { store, persistor } = getOrCreateStore(props.initialState);
this.reduxStore = store;
this.reduxPersistor = persistor;
}
render() {
return (
<App
{...this.props}
reduxStore={this.reduxStore}
reduxPersistor={this.reduxPersistor}
/>
);
}
}
};
This skips redux-persist
on server; and somehow, it just works.
I am getting the following error when pages is being first loaded:
I have scrutinized my code a thousand times and can't found nothing wrong:
Everything works fine - I mean, after page has loaded even with error, changes made to state are persisted to IndexedDB, data are encrypted etc.; and if I refresh the page, even with error, I can see the state saved on IndexedDB is still there, untouched. But no matter what I do, I am getting the same error since the first time I ran
npm run dev
(which callsnext
).Any help? Pleaaase :)