brocoders / redux-async-connect

It allows you to request async data, store them in redux state and connect them to your react component.
645 stars 103 forks source link

Deferred promise does not fire on the client-side when in server-rendering mode #72

Open djeeg opened 8 years ago

djeeg commented 8 years ago

Hey @sars, this async project works really well, easy to understand and integrate, especially the new deferred vs not-deferred logic Thought I'd report this slight issue First point to note, this is not an issue when using client-side navigation It only becomes a problem on the initial server-side page request

I have a page, where I want the server to render 20% (fast) of an object and leave the client to fetch the other 80% (slow) 20% of the object is enough to push out the SEO tags

asyncConnect is setup like this:

const AsyncConnectedUserView = asyncConnect([{
    deferred: false,
    promise: ({store: {dispatch, getState}, params: {id}}) => {
        return Promise.resolve(dispatch(fetchShallowUserThunk(dispatch, id)));
    }
}, {
    deferred: true,
    promise: ({store: {dispatch, getState}, params: {id}}) => {
        return Promise.resolve(dispatch(fetchDeepUserThunk(dispatch, id)));
    }
}])(ConnectedUserView)

And the server bindings: (a bit messy as using TS with no spread, and https://github.com/Rezonans/redux-async-connect/issues/55#issuecomment-204619076)

var cloned = {};
for(var i in renderProps) {
    cloned[i] = renderProps[i];
}
cloned["store"] = store;
cloned["filter"] = (item) => {
    return !item.deferred
};
loadOnServer(cloned).then(() => {
    const appHTML = renderToString(
        <Provider store={store} key="provider">
            <ReduxAsyncConnect {...renderProps} />
        </Provider>
    )

And client bindings:


<Provider store={store} key="provider">
    <Router history={history} children={routes} render={(props) =>
        <ReduxAsyncConnect {...props} />
    } />
</Provider>

The problem I have, is that I would expect that on server render, the server waits for fetchShallowUserThunk (which it does) And then the client should trigger fetchDeepUserThunk (which it doesn't) It is like the [deferred: true] flag does not do anything

I can work around this by doing something like this

class UserView extends React.Component<IProps, any> {
    componentDidMount() {
        this.props.dispatch(fetchDeepUserThunk(this.props.dispatch, this.props.params.id));     
    }
}

Though, that's not ideal as I multiple calls to fetchDeepUserThunk

Have I missed something? Cheers

hanjukim commented 8 years ago

I'm facing at this problem too. Turning SSR off was my temporary fix.

danramosd commented 8 years ago

Having the same issue, turned off SSR and it worked for me, thanks @hanjukim

FrankPaul1 commented 7 years ago

What is SSR? and how to turn it off?

pie6k commented 7 years ago

@FrankPaul1 - it's Server Side Rendering