with-redux-thunk
Async thunk does not work in SSR
The example repo: with-redux-thunk
In the above example, serverRenderClock is synchronous
```synchronous dispatch
export const serverRenderClock = isServer => dispatch => {
return dispatch({ type: actionTypes.TICK, light: !isServer, ts: Date.now() })
}
everything work expected, on SSR, the example will render the time on the server
However, if we try to make serverRenderClock async, it breaks
using below async serverRenderClock
```async dispatch
export const serverRenderClock= usServer = dispatch => {
return setInterval(() => {
dispatch({ type: actionTypes.TICK, light: !isServer, ts: Date.now() })
}, 1000)
}
The new getInitialProps
static async getInitialProps ({ reduxStore, req }) {
const isServer = !!req
await reduxStore.dispatch(serverRenderClock(isServer))
return {}
}
With the new async dispatch, it should also render the server time as synchronous
Above is an generalized example. However, let's say if we want to dispatch an async thunk with API call in server, the scenario is similar
For example, making async api call in thunk in the server side
getResultFromApi = () => async dispatch => {
const response = await fetch('http://www.test-api.com')
const data = await response.json()
dispatch(setSuccessResponseAction(data)
}
How can I use above async thunk in my getInitialProps so SSR works properly?
You need to return a promise in serverRenderClock
return new Promise(resolve => {
setTimeout(() => {
resolve(dispatch({ type: actionTypes.TICK, light: !isServer, ts: Date.now() }))
}, 5000)
})
@MarchWorks I also tried Promise but it's not working either. For example, below is my promise
export function fetchListingCount() {
return (dispatch: any) =>
axios
.get("my-listing-count-endpoint.com")
.then(({ data }) => data)
.then(data => dispatch(setTotalListingCount(data.ListingCount))); //my action to set the listing count
}
I then used above function in my getInitialProps
static async getInitialProps(props: any) {
const { store } = props.ctx;
await store.dispatch(fetchListingCount());
console.log(store.getState());
}
I can see from the console.log that redux store on the server side has the listingCount populated
However, when rendered on client side, the listingCount is still 0 (initial value)
@JoeDevGeeeee hey! redux-thunk works fine in my project but I'm using https://github.com/kirill-konshin/next-redux-wrapper
I've checked this example and if you replace with-redux-store lib in here with next-redux-wrapper then it works
@JoeDevGeeeee your example doesn't return a promise do what I commented above
@MarchWorks I used your comment to reproduce the issue so can confirm thatwith-redux-thunk doesn't work for me
@meuwka check it here https://codesandbox.io/s/helloworld-37ycq click on Open in new window (not necessary just to see the delay more clearly.) it will take 10 seconds before the page render
@MarchWorks interesting. even using the same dependencies versions can't make it locally. keep getting 00:00:00 from the server
@meuwka I can't see a significant difference between next-redux-wrapper and with-redux-store but in next-redux-wrapper _app there is
static async getInitialProps ({ Component, ctx }) {
return {
pageProps: Component.getInitialProps
? await Component.getInitialProps(ctx)
: {}
}
}
which doesn't exist in with-redux-thunk so can you try adding it.
But maybe it has something to do with node version (which doesn't make sense because it does work for next-redux-wrapper)
@MarchWorks yes, you're right. I've found that getInitialProps in index.js is not async https://github.com/zeit/next.js/blob/0dbd3b98eca0bee01a05b8414a60c48abba76abd/examples/with-redux-thunk/pages/index.js#L7
it has to be this way:
static async getInitialProps({ reduxStore, req }) {
const isServer = !!req;
await reduxStore.dispatch(serverRenderClock(isServer));
return {};
}
@timneutkens Should be closed
How did you guys fixed it? I am having an issue where store.dispatch is not getting called in getInitialProps also, something like:
static async getInitialProps(props) {
const {
store,
} = props.ctx;
await store.dispatch(fetchData());
return {};
}
But I don't see the data in the redux store when loaded?
@itsmichaeldiego try this
const {
store,
} = props;
and check if it's called store in your props
Most helpful comment
@MarchWorks yes, you're right. I've found that
getInitialPropsinindex.jsis not async https://github.com/zeit/next.js/blob/0dbd3b98eca0bee01a05b8414a60c48abba76abd/examples/with-redux-thunk/pages/index.js#L7it has to be this way: