Fetching data after a route transition in React Router can be confusing at first, but there's a fairly easy solution using the React lifecyle event componentDidMount. If you're working with a universal app, when you hit a component straight at it's url, say /me/friends, you'll already have the data via the initial state. But, when you come to that page via a client side react router render, how do you grab the data?

The componentDidMount method only fires when the component renders on the client side. This means if you go directly to the Hattie B's page, the data will already have been fetch server side, so the this.props.poi will already be defined and passed through the page's intitialState.

However, when you come to the detail page via the list, the POI will be empty because it hasn't been fetch yet. Now we can talk about how to use async and await from es2017 to create a nice clean actionCreator. Make sure you have babel-polyfill, and either babel-env or babel-preset-es2017 available to be able to use the async await goodies.

So here we create an async arrow function. We can use redux-thunk to get dispatch passed in as an argument. Then use the new fetch API to await for the response, await for the JSON to be downloaded, and then dispatch the final data so the reducer can add the POI to the state.

From their connect simply passes the POI into the component.

Conclusion

Hopefully if you're working on a universal app with React Router, this will help you get your components loaded with data on the client side. Universal apps can definitely be tricky, but in the end, they're extremely powerful and fun to work with!