markdalgleish / redial

Universal data fetching and route lifecycle management for React etc.
1.1k stars 42 forks source link

Nested routes - prevent fetching data on parent routes when navigate to child route #16

Closed joehua87 closed 8 years ago

joehua87 commented 8 years ago

Hello, Thank you for your awesome lib, it helps a lot :smiley:

I face some problem when working with nested route.

Given we have route like:

  <Route path="/" component={App}>
    <Route path="user" component={User}>
      <Route path=":username" component={UserDetail}/>
    </Route>
  </Route>

Question: Does we have any way to prevent reloading users everytime we navigate to /user/:username? Can we provide current state in fetch function like this?

const hooks = {
  fetch: ({ dispatch, query: { keyword, repos, followers }, entities }) => {
    if (!entities) { // Only reload entities when entities doesn't exists to prevent duplicated load
    return dispatch(getUsers({ keyword, repos, followers }))
    }
  }
}
joehua87 commented 8 years ago

You can see the example here: http://45.79.94.169:3000/user

maslianok commented 8 years ago

@joehua87, you can pass store through locals and then check the global state, e.g.

// Set up Redux (note: this API requires redux@>=3.1.0):
  const store = createStore(reducer, initialState, applyMiddleware(thunk));

  // Listen for route changes on the browser history instance:
  browserHistory.listen(location => {
    // Match routes based on location object:
    match({ routes, location }, (error, redirectLocation, renderProps) => {
      // Get array of route handler components:
      const { components } = renderProps;

      // Define locals to be provided to all lifecycle hooks:
      const locals = {
        path: renderProps.location.pathname,
        query: renderProps.location.query,
        params: renderProps.params,

        // ----------CHANGED-------- Pass store here
        store
      };
      ...
    });
  });

Use store.getState() in your hooks:

const hooks = {
  fetch: ({ store: {dispatch, getState}, params: { id } }) => {
    if (!getState().entities)
      return dispatch(getSomething(id));
    }
  }
};
joehua87 commented 8 years ago

Thank you @maslianok, I forget about it's possible to pass store into local :)