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

load data again on client side #43

Open snowcxt opened 8 years ago

snowcxt commented 8 years ago

I use ReduxAsyncConnect with react-intl

const component = (
  <Router render={(props) => <ReduxAsyncConnect {...props} helpers={{client}} filter={item => !item.deferred} />} history={browserHistory}>
    {getRoutes(store)}
  </Router>
);

ReactDOM.render(<Provider key="provider" store={store}>
  <IntlProvider locale={locale} messages={localeMessages}>
    {component}
  </IntlProvider>
</Provider>, dest);

But code in asyncConnect run again on the client side:

@asyncConnect([{
  promise: ({store: {dispatch, getState}}) => {
    const promises = [];
    // something here ...

    return Promise.all(promises);
  }
}])
sars commented 8 years ago

I use react-intl too : https://github.com/sars/appetini-front/blob/appetini/src/client.js#L29 https://github.com/sars/appetini-front/blob/appetini/src/helpers/rootComponent.js

I didn't catch what problem do you face?

snowcxt commented 8 years ago

For example I use @asyncConnect for the home page. When I go to http://localhost:3000/, I will expect the promise runs on the server side only. But it ran on the server and client side.

I think I could just misconfigure something. I’m using version 1.0.0-rc2.

snowcxt commented 8 years ago

I think this problem is caused by

  componentWillReceiveProps(nextProps) {
    this.loadAsyncData(nextProps);
  }

It works correctly for the initial load when I remove this code. I changed the code to this. It works for me:

  componentWillReceiveProps(nextProps) {
    if (this.props.location.pathname !== nextProps.location.pathname) {
      this.loadAsyncData(nextProps);
    }
  }

Hopefully this information can help you to investigate the issue

sars commented 8 years ago

@snowcxt if you don't want to delay transition on client , please see https://github.com/Rezonans/redux-async-connect/issues/42

if you want to not reload asyncConnect - you can implement it in decorator...

snowcxt commented 8 years ago

The problem is that: this code runs twice (both on server side & client side)

@asyncConnect([{
  promise: ({store: {dispatch, getState}}) => {
    const promises = [];
    /* 
     Should only run the server side for the page initial load. 
     But it run on the client side as well.
    */
    // something here ...
    return Promise.all(promises);
  }
}])
sars commented 8 years ago

@snowcxt , probably you forgot to connect redux-async-connect reducer?

smad commented 8 years ago

I encounter the same problem with my project. The promise run both on server and client.

In my componenent, i'm changing the state in ComponentDidMount and asyncconnect re run the promise on client. I test the filter with the option defered <ReduxAsyncConnect {...props} helpers={{client}} filter={item => !item.deferred} /> but is the same.

The snowcxt's solution work for me but is not very clean to change code on module.

Sorry for my bad english