bananaoomarang / isomorphic-redux

Isomorphic Redux demo, with routing and async actions
https://medium.com/@bananaoomarang/handcrafting-an-isomorphic-redux-application-with-love-40ada4468af4
MIT License
455 stars 87 forks source link

How to fetch data at move link (using react-router <Link>)? #40

Closed zenato closed 7 years ago

zenato commented 8 years ago

I append custom url in routes.jsx.

export default (
  <Route name="app" component={App} path="/">
      <IndexRoute component={Home}/>
      <Route path="/about" component={About}/>
  </Route>
);

And, wrote About.jsx:

render() {
  return (
    <div>
      This is About Page.
      <Link to={'/'}>Go to Index</Link> // react-router Link Component
    </div>
  );
}
  1. open browser and connect http://localhost:3000/about.
  2. And Click Go to Index.
  3. Appear TodoApp, but didn't fetch server data.

Fetch initial data server side and render the jsx components but it works only if the url is directly hit, not following links. (server side render using lib/fetchComponentData)

How to fetch data at move link?

bananaoomarang commented 8 years ago

You can use the onEnter route prop, with a callback for this:

https://github.com/rackt/react-router/blob/latest/docs/API.md#router

zenato commented 8 years ago

@bananaoomarang onEnter is server + client twice call. :(

fahrradflucht commented 8 years ago

Can some one provide an example on how to fetch server data with the onEnter hook?

fahrradflucht commented 8 years ago

Okay, got it but I also now have the problem, that onEnter is called on the client and on the server.

I tried checking in the onEnter method if the store already contains the otherwise needed data, but it's empty if the server fetched it, so I'm not sure why, since we encode the state don't we?

Edit: We don't! We only encode the data that we fetch through that needed thingy.

fahrradflucht commented 8 years ago

Okay I think you have to do the dirty if ((typeof window !== 'undefined') thing so that your onEnter fetch is only executed on the client. Then you still do the needed thingy to fetch the data on the server. This way you're able to check if the store already contains the needed data and fetch it otherwise.

Example:

const getTodo = (nextState, replaceState) => {
    const todos = store.getState().todos;
    if ((typeof window !== 'undefined') && (todos.get('id') === undefined)){

        store.dispatch(TodoActions.getTodo(nextState.params));

    }
};

Seems quite dirty to me, isn't it?