Server side rendered page displays for a second and then page re renders on client side and state seems to be empty
See original GitHub issueI am using Redux-saga to manage my states and to manage my API calls. My page renders properly on Server side and correct html is sent to client. The issue here is on client side my page renders again and the state on client side seems to be different from that of server.
In my project i have multiple containers and components and i am combining my reducers and sagas. The Code Is as Follows:
Store
import { createStore, applyMiddleware, compose } from 'redux';
import withRedux from 'next-redux-wrapper';
import thunkMiddleware from 'redux-thunk';
import { fromJS } from 'immutable';
import nextReduxSaga from 'next-redux-saga';
import createSagaMiddleware from 'redux-saga';
import mainSagas from './sagas';
import reducer, { initialState } from './reducers';
const sagaMiddleware = createSagaMiddleware()
export function configureStore (state = initialState) {
const middlewares = [
sagaMiddleware,
thunkMiddleware,
];
const store = createStore(
reducer,
fromJS(state),
compose(applyMiddleware(...middlewares)),
);
store.sagaTask = sagaMiddleware.run(mainSagas);
return store
}
export function withReduxSaga (BaseComponent) {
return withRedux(configureStore)(nextReduxSaga(BaseComponent))
}
Reducers.js
import { combineReducers } from 'redux'
import homeReducer, { initialState as homeState } from 'containers/Home/reducer';
import rootReducer, { initialState as rootState } from 'containers/Root/reducer';
import aboutUsReducer, { initialState as aboutUsState } from 'containers/AboutUs/reducer';
import contactUsReducer, { initialState as contactUsState } from 'containers/ContactUs/reducer';
import portfoliosReducer, { initialState as portfoliosState } from 'containers/Portfolios/reducer';
import portfolioReducer, { initialState as portfolioState } from 'containers/Portfolio/reducer';
import { fromJS } from 'immutable';
export const intitialState = fromJS({
home: homeState,
root: rootState,
aboutUs: aboutUsState,
contactUs: contactUsState,
portfolios: portfoliosState,
portfolio: portfolioState
});
export default combineReducers({
home: homeReducer,
root: rootReducer,
aboutUs: aboutUsReducer,
contactUs: contactUsReducer,
portfolios: portfoliosReducer,
portfolio: portfolioReducer,
})
Sagas.js
import { fork } from 'redux-saga/effects'
import homeSagas from 'containers/Home/sagas';
import rootSagas from 'containers/Root/sagas';
import aboutUsSagas from 'containers/AboutUs/sagas';
import contactUsSagas from 'containers/ContactUs/sagas';
import portfoliosSagas from 'containers/Portfolios/sagas';
import portfolioSagas from 'containers/Portfolio/sagas';
export default function* mainSagas() {
yield [
fork(homeSagas),
fork(rootSagas),
fork(aboutUsSagas),
fork(contactUsSagas),
fork(portfoliosSagas),
fork(portfolioSagas),
]
}
index.js (Landing Page) In the Saga i simply make the API call and set the data in the state. It is working fine
import React from 'react';
import HomeContainer from 'containers/Home';
import { withReduxSaga } from 'store'
import {
getSettings,
getAboutUs,
getTeam,
getServices,
getPortfolio,
getPortfolioSettings,
getTestimonials
} from 'containers/Home/actions';
class Home extends React.Component {
static async getInitialProps({ store }) {
await store.dispatch(getSettings())
await store.dispatch(getAboutUs())
await store.dispatch(getTeam())
await store.dispatch(getServices())
await store.dispatch(getPortfolio())
await store.dispatch(getPortfolioSettings())
await store.dispatch(getTestimonials())
}
render() {
return (
<HomeContainer />
);
}
}
export default withReduxSaga(Home)
I am using ‘Reselect’ to select the data from state. Selector.js
import { createSelector } from 'reselect';
const selectHomeState = () => (state) => state.home;
const selectSettings = () => createSelector(
selectHomeState(),
(homeState) => homeState.get('Settings')
);
const selectGetSettingsStatus = () => createSelector(
selectHomeState(),
(homeState) => homeState.get('getSettingsStatus')
);
const selectAboutUs = () => createSelector(
selectHomeState(),
(homeState) => homeState.get('AboutUs')
);
const selectGetAboutUsStatus = () => createSelector(
selectHomeState(),
(homeState) => homeState.get('getAboutUsStatus')
);
const selectTeam = () => createSelector(
selectHomeState(),
(homeState) => homeState.get('Team')
);
const selectGetTeamStatus = () => createSelector(
selectHomeState(),
(homeState) => homeState.get('getTeamStatus')
);
const selectServices = () => createSelector(
selectHomeState(),
(homeState) => homeState.get('Services')
);
const selectGetServiceStatus = () => createSelector(
selectHomeState(),
(homeState) => homeState.get('getServicesStatus')
);
const selectTestimonials = () => createSelector(
selectHomeState(),
(homeState) => homeState.get('Testimonials')
);
const selectGetTestimonialsStatus = () => createSelector(
selectHomeState(),
(homeState) => homeState.get('getTestimonialsStatus')
);
const selectPortfolios = () => createSelector(
selectHomeState(),
(homeState) => homeState.get('Portfolios')
);
const selectGetPortfoliosStatus = () => createSelector(
selectHomeState(),
(homeState) => homeState.get('getPortfoliosStatus')
);
const selectPortfolioSettings = () => createSelector(
selectHomeState(),
(homeState) => homeState.get('PortfolioSettings')
);
const selectGetPortfolioSettingsStatus = () => createSelector(
selectHomeState(),
(homeState) => homeState.get('getPortfolioSettingsStatus')
);
export {
selectSettings,
selectGetSettingsStatus,
selectAboutUs,
selectGetAboutUsStatus,
selectTeam,
selectGetTeamStatus,
selectServices,
selectGetServiceStatus,
selectTestimonials,
selectGetTestimonialsStatus,
selectPortfolios,
selectGetPortfoliosStatus,
selectPortfolioSettings,
selectGetPortfolioSettingsStatus
};
When i reload the page my server side rendered page is displayed and then with a flicker all data is lost. And page without data is displayed. When i do view page source i can see the correct html sent from the server.
I could not figure out the issue. Any help in this regard will be appreciated.
- I have searched the issues of this repository and believe that this is not a duplicate.
Expected Behavior
Current Behavior
Steps to Reproduce (for bugs)
Context
Your Environment
Tech | Version |
---|---|
next | 4.1.4 |
node | >=6 |
OS | win 10 |
browser | chrome |
etc |
Issue Analytics
- State:
- Created 6 years ago
- Comments:21 (8 by maintainers)
Top GitHub Comments
take a look to the examples in next with redux
Replace
fromJS(state)
in the Store tostate
and then addfromJS
directly to your reducers. Immutable in the NextJS is a pain.