Getting started with create-react-app, Redux, React Router & Redux Thunk
We are going to build the following
There is a fantastic tool on the block endorsed by React that boasts “no configuration necessary”.
I use create-react-app for every new React application. It’s so good 💯.
The great thing Create React App has bundled is the eject tool, which allows you to completely disconnect and add your own advanced configuration.
Seriously though, this is not required to add things like Redux, React Router & Redux Thunk.
This tutorial assumes you have a good fair understanding of Redux. Check out this tutorial on Egghead by Dan Abramov if you want to see what all the Redux fuss is about.
Let’s get to it!
Let’s go ahead and create a new React app.
npx create-react-app react-redux-example
Before we add any code, let’s go ahead and install all our dependencies.
npm install --save redux react-redux react-router-dom connected-react-router redux-thunk history
Note: All of the files we’ll create below are to be saved within the
1. The Store
Everything in Redux belongs in a single store. Let’s configure our store to understand react-router and redux-thunk.
Within our store, we’re importing a few core modules from Redux that allows us to create a custom global store.
redux-thunk are both known as middleware to Redux and we need to configure our store to treat them that way.
You’ll notice we’re importing a file we haven’t yet created called
rootReducer. This is essential to Redux. We’ll come back to Reducers later but for now, create a file called
./src/modules/index.js so we can satisfy our Store.
store const creates a store using the Redux
createStore function. It accepts a rootReducer, initialState and an enhancer in this example.
history const syncs our
browserHistory with our
store and must be exported so we can use it within our routes later.
We also must export our
storeconst as the default module so that it can also be used later.
This tutorial uses React Router v4 which allows us to mount components anywhere inside our application when a given url matches our defined parameters.
In previous versions of React Router you might see files like
routes.js which contain a long list of nested routes but React Router v4 does routing a little differently.
Our router history is managed inside our Redux store which we created in the first section and is passed down via something called
ConnectedRouter which we will implement later.
We’ll get started by defining which components to show at what url in our first container component
First, create our
App component that renders navigation and any matching routes inside a
Now let’s create our
Home component that we defined to show at the exact path of
This should be straight forward for those who have used Redux before but what is special in this example is we can import
connected-react-router and use within our action creator.
Since our Store knows about
connected-react-router it can manage and act on routing actions. Magic! 💥
Finally, create the
About component to allow our router to actually do something.
4. Rendering our app
The time has come to mount our application.
We need to tell
react-dom to render our application with the correct store and browser history data. We do this by using the
ConnectedRouter export given to us by React Router v4.
ConnectedRouter has access to the
store given to
Provider so you don’t need to worry about passing data through any additional props.
React Router magic 💥!
5. Adding Redux Thunk
It’s 2018 and your React application is most likely going to be crawling with async functions. Redux Thunk is middleware for Redux that allows you to write action creators that return a function instead of an action.
That totally made no sense, so let’s see an example!
Let’s go ahead and create some actions and a reducer for a counter.
decrementAsync functions return a Thunk. We first dispatch an action and we wrap another function within
setTimeout() which dispatches when the timer is up. 🙌
We’ll need to hook up our
counter.js to our
rootReducer so our store can manage our state.
To complete our thunk example, let’s update our
Home container component to include our Counter state and actions.