markdalgleish/redial

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

joehua87 opened this issue ยท 3 comments

Hello, Thank you for your awesome lib, it helps a lot ๐Ÿ˜ƒ

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>
  • Render /user:
    • Server: ok
    • Client: ok
  • Render /user/:username
    • Server: ok
    • Client: problem - the users list will reload everytime we navigate to /user/:username

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 }))
    }
  }
}

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

@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));
    }
  }
};

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