I’m struggling to get server-side rendering (SSR) to work with redux-api
. The app works fine with just client-side rendering (CSR).
For SSR to work, I need the data to be available in Next.js’ getInitialProps
function. I’m trying to use next-redux-wrapper
to bind it together.
Current status:
class ShowLessonPage extends React.Component {
static async getInitialProps ({store, isServer, pathname, query}) {
console.log(`getInitialProps`, {store, isServer, pathname, query});
const { dispatch } = store;
const lessonSlug = query.lessonSlug;
// Get one Lesson
dispatch(reduxApi.actions.oneLesson({ id: `slug=${lessonSlug}` }));
}
render() {
console.log('render', this.props.oneLesson);
const lesson = this.props.oneLesson.data;
//...
}
//.....
}
const createStoreWithThunkMiddleware = applyMiddleware(thunk)(createStore);
const reducer = combineReducers(myReduxApi.reducers); // redux-api
const makeStore = function (state, enhancer) {
return createStoreWithThunkMiddleware(reducer, state);
}
const mapStateToProps = function (state) {
return { oneLesson: state.oneLesson };
};
// withRedux = next-redux-wrapper
const ShowLessonPageConnected = withRedux({ createStore: makeStore, mapStateToProps: mapStateToProps })(ShowLessonPage)
export default ShowLessonPageConnected;
I at least get store
into getInitialProps
now, but I get a strange Error: only absolute urls are supported
message that I didn’t have in my CSR (pre-withRedux
) version of the app. And this.props.oneLesson.data
is of course empty.
makeStore
is getting a state
=undefined
on the server generated calls, maybe that’s a clue.
I’m also open to replacing redux-api
with something else that works similarly.
UPDATE 1: by making all URLs full, Redux is now hitting my API endpoint. However, for 1 page reload it calls makeStore
no less than 3 times, and only the first call contains the correct slug, see console output:
makeStore { state: undefined, reqParams: { lessonSlug: 'tyrannosaurus-rex' } }
getInitialProps { query: { lessonSlug: 'tyrannosaurus-rex' } }
API: GET request: { _id: 'slug=tyrannosaurus-rex' }
makeStore { state: undefined, reqParams: { lessonSlug: 'undefined' } }
getInitialProps { query: { lessonSlug: 'undefined' } }
API: GET request: { _id: 'slug=undefined' }
makeStore { state: undefined, reqParams: { lessonSlug: 'undefined' } }
getInitialProps { query: { lessonSlug: 'undefined' } }
API: GET request: { _id: 'slug=undefined' }
UPDATE 2: A breakthrough: returning a promise from getInitialProps
makes SSR work. Now client-side rendering is acting up, funny enough.
static async getInitialProps ({store, isServer, pathname, query}) {
const { dispatch } = store;
const lessonSlug = query.lessonSlug;
const resultPromise = await dispatch(reduxApi.actions.oneLesson({ id: `slug=${lessonSlug}` }));
return resultPromise;
}