Learning React Redux & Router
I love having a nice side project, to learn something new and keep up with the web.
Starting out on a new project with React, I decided it was time I learnt a few new things: mostly Redux and React-Router, with a bit more ES6 thrown in for good measure! Even though Dan says You might not need Redux, everyone’s talking about it so there must be something worth looking at…
Starting with Redux
Where to start? The tutorial at redux.js.org seemed the obvious choice. The introduction made a lot of sense and the sections on actions, reducers and store were pretty straight-forward. Even the unfamiliar ES6 arrow functions were cool! Looking good so far…
Usage with React
The learning curve starts ramping up a bit with React-Redux and really blasts off in the “Advanced”
But with the finishing line in sight I muddled through this and
section and I was done!
I even managed to build all this into my nascent app. But something was missing, and trying to fix it flummoxed me for a while…
The missing link
The tutorial was great, but I found that it missed one vital piece of info. In any app that uses React Router and loads data via Async Actions, you need to link these. However, it’s not clear where this linking should happen.
From previous React experience, I knew that you can use a component’s
componentDidMount function to kick off loading
of data. For this to work with React Router and Redux, you’d need a single component
to have access to the url parameter AND the Redux store.
OK, I can do this…
This worked OK initially: when first visiting a url, E.g. /users/:userId/ the
userId to load the specified
user. However, when the url changes
to a new
userId, nothing new is loaded since
componentDidMount is not fired again.
fetchUser(userId) under other lifecycle methods just got me into endless loops. 😢😖
Looking for a solution
Googling for a solution picked up some promising results: firing actions in response to route transitions in react-router described the exact issue I was having! This led to React router integration, which led to Docs: Usage with React Router. However, these discussions contained so many different opinions and examples that it was impossible for newbie-me to identify a solution. It didn’t help that many examples used older versions of Redux and Router. But when Dan committed to writing the docs I felt the answer was within my grasp!
So, it was kinda frunstrating to find that issue was close with this PR which was part of the tutorial I’d already covered! So, back to square 1.
Eventually I looked at the Redux examples. Only the Real World Example had the solution I needed, but it was a lot more complex than anything covered before and took a long time before I could get into it.
I finally found what seemed to be the solution.
I needed to add this alongside the
componentWillMount() from above:
To consolidate everything above, I wanted to try and write my own minimal Real World Example that loaded users from the github api.
This was harder than expected and I ended up starting from scratch with the React Router tutorial.
I used the lesson 10
example as my starting point and built the app on top of that.
hashHistory instead of
browserHistory which makes it easier
to host on a static page.
Try the example
And here’s the app embedded in this page. You’ll see the url hash change in the browser when you click and load users:
Is this right?
It seems wrong to need a UI component to fetch data in response to url changes. Surely the Redux store itself should be able respond to url changes and fetch data as needed?
Is this what React Redux Router is for? That’s probably the next thing I need to look at.
I’d be interested to know if others have found this issue tricky, or maybe this would be a no-brainer if I was a bit more fluent in React before starting React Redux.
Thanks for reading to the end!