Redux First Steps: Shotgun Episode 5
Shotgun is a video screencast show that lets you ride shotgun with me while I tackle real programming challenges for real apps and libraries. The show is only available to members of EricElliottJS.com, but I’m journaling the adventures here.
If you haven’t cloned the app yet, do that first:
git clone firstname.lastname@example.org:jshomes/course-player.git
Make sure your local copy is up to date, and then check out the starting point for this episode:
git fetch — all && git merge origin/master
git checkout episode-5-start
Then to run the testing console:
npm run watch
You should be all set now to follow along and see how the changes effect things in the browser and the unit tests at the same time.
We’ve built out the basic course player UI, which walks users through a playlist of information cards, called a deck. Now it’s time to add our state management features, and for that, we’re using Redux. To learn more about Redux architecture, check out “10 Tips for Better Redux Architecture”.
Redux First Steps
The core building block of Redux is the reducer function. A reducer function is a function that gets applied to every element in a collection or stream in order to reduce the data to a single value — in this case, the application’s state.
Reducers take two arguments, the current state, and the data to be applied, and return the next state:
reducer(state, action) => nextState
In Redux, the reducer is the single source of truth for state, and it is responsible for determining its own initial state, so the first step to building a reducer is to determine the store shape and return the default state if the reducer receives no arguments.
I always start building reducers with a unit test to be sure that the reducer is returning the correct default state, but instead of hard-coding that state, I create a factory that I can call from any of the unit tests:
This way, I can reuse the factory to create whatever state I need for the test at hand. Another benefit of the factory is that if the state shape changes, I only have to change it in one place, instead of in potentially many unit tests.
- Given the same arguments, always return the same value.
- No side-effects.
I have always liked the idea of using immutable data structures for application state, but after using reducers with teams, it became clear that accidental state mutations are fairly common, even with groups of smart developers.
Even with immutable state, you should still be careful not to mutate the action object or any shared mutable state outside the reducer.
Remember, reducers should follow some simple rules:
- Given no state, reducers should always return valid initial state.
- Reducers should be pure functions. You can use immutable data structures like Immutable.js to help you avoid accidental state mutation.
He spends most of his time in the San Francisco Bay Area with the most beautiful woman in the world.