The Simplest React Redux tutorial I wish I had when I started learning here
When I first started learning Redux I wish I could find the simplest tutorial ever.
Despite the great resource out there I couldn’t wrap my head around some of the Redux concepts.
I knew what’s the state. But Actions, action creators, and reducers? They were obscure for me.
Last but not least I didn’t know how to glue React and Redux together.
During those days I started writing my own React Redux tutorial and since then I learned a lot.
I taught myself the Redux fundamentals by writting this guide. I hope it’ll be useful for all those learning React and Redux.
¶React Redux tutorial: who this guide is for
The following React Redux guide is exactly what you’re looking for if:
- you have a good grasp of Javascript: ES6, and React
- you’re looking forward to learn Redux in the most simple way
¶React Redux tutorial: what you will learn
In the following guide you will learn:
- what is Redux
- how to use Redux with React
¶React Redux tutorial: a minimal React development environment
Before starting off make sure you have a React development environment ready to roll.
To make one you can follow this tutorial of mine: How to set up React, webpack, and Babel or you can also use create-react-app.
¶React Redux tutorial: what is the state?
To understand what is Redux you must first understand what is the state.
If you have ever worked with React the term state should be no surprise to you.
I guess you already wrote some stateful React component:
1 | import React, { Component } from "react"; |
A stateful React component is a Javascript ES6 class.
Every stateful React component carries its own state.
In a React component the state holds up data and the component might render such data to the user.
The state could also change in response to actions and events: in React you can update the local component’s state with setState.
But what is the state anyway?
The term state is not tied exclusively to React.
The state is all around you.
Even the simplest JavaScript application has a state.
Consider the following example:
the user clicks a button
a modal appers afterwards
Guess what, in this trivial interaction there is a state we must deal with.
We could describe the initial state as a plain JavaScript object:
1 | var state = { |
And when the user clicks the button we have:
1 | var state = { |
How do you keep track of those things in JavaScript besides storing the state in an object?
Is there a library that can help use tracking the state?
¶React Redux tutorial: what problem does Redux solve?
A typical JavaScript application is full of states. And you didn’t even know.
Here are some examples of state:
- what the user sees (data)
- what data are we fetching
- what URL are we showing to the user
- what items are selected inside the page
- are there errors in the applications? That’s state too
State is everywhere in JavaScript.
As you can see even the simplest JavaScript application has a state.
But can you imagine how much state a React application has?
Yeah, you can get by with keeping the state within a parent React component.
As long as the application remains small.
Then things will become tricky.
Even a silly to-do list could become unmanageable if you starting passing the state up and down.
Who wants a bloated React component?
Not only, I’d say that the frontend shouldn’t know about the business logic. Ever.
So what are the alternatives for managing the state of a React component?
Redux is one of them.
Redux solves a problem that might not be clear in the beginning: it helps giving each React component the exact piece of state it needs.
Redux holds up the state within a single location.
Also with Redux the logic for fetching and managing the state lives outside React.
The benefits of this approach might be not so evident. Things will look clear as soon as you’ll get your feet wet with Redux.
In the next section we’ll see why you should learn Redux and when to use Redux within your applications.
¶React Redux tutorial: should I learn Redux?
Are you trying to learn Redux but you’re going nowhere?
Redux literally scares most beginners. But that shouldn’t be your case.
Redux is not that hard. The key is: don’t rush learning Redux just because.
You should start learning Redux if you’re motivated and passionate about it.
Take your time.
I started to learn Redux because:
- I was 100% interested in learning how Redux works
- I was eager to improve my React skills
- the combination React/Redux is ubiquitous
- Redux is framework agnostic. Learn it once, use it everywhere (Vue JS, Angular)
Learning Redux or an equivalent state management library is a must.
Another truth is: real world JavaScript applications make always use of a state management library.
State is so pervasive and hard that state management in JS is still an unsolved problem.
The amount of libraries that come out almost daily is a proof.
Redux is just a library among the others, yet it is one of the most important.
Will Redux disappear in the future? Maybe.
But the patterns will stick forever.
Would you neglet learning OOP with PHP just because PHP is not “trendy” anymore?
I advise not doing so.
The same with Redux.
You should learn the patterns for managing UI state because they will be invaluable in your career.
¶React Redux tutorial: should I use Redux?
Using Redux or Flux (or Mobx) for state management is up to you.
Maybe you need none of these libraries. They have a cost: they add another layer of abstraction to your application.
But I prefer thinking about Redux as an investment, not as a cost.
Another common question for Redux beginners is: how do you know when you’re ready to use Redux in your application?
If you think about it there is no rule of thumb for determining when you do need Redux for managing the state.
Redux also offers a lot of convenience for a JavaScript developer. Debugging, action replaying. And much more.
When I start a new React project I’m always tempted to add Redux straight away. But …
As developers we overengineer our code automatically.
So, when should you add Redux to a project?
Before picking Redux take your time to explore alternative patterns. In particular try to get the most out of React’s state and props.
Dave Ceddia has a nice writeup with a lot of great insights for using children props as an alternative before reaching for Redux.
And don’t forget that a React project can be easily refactored to include Redux later.
What I found is that you should consider using Redux when:
- multiple React components needs to access the same state but do not have any parent/child relationship
- you start to feel awkward passing down the state to multiple components with props
If that makes still no sense for you do not worry, I felt the same.
Dan Abramov says “Flux libraries are like glasses: you’ll know when you need them.”
And in fact it worked like that for me.
Before going further take your time to understand what problem does Redux solve and whether you’re motivated or not to learn it.
Be aware that Redux is not useful for smaller apps. It really shines in bigger ones. Anyway, learning Redux even if you’re not involved in something big wouldn’t harm anyone.
In the next section we’ll start building a proof of concept to introduce:
- the Redux fundamental principles
- Redux alongside with React
¶React Redux tutorial: getting to know the Redux store
Actions. Reducers. I kind of knew about them. But one thing wasn’t clear to me: how were all the moving parts glued together?
Were there some minions or what?
In Redux there are no minions (unfortunately).
The store orchestrates all the moving parts in Redux. Repeat with me: the store.
The store in Redux is like the human brain: it’s kind of magic.
The Redux store is fundamental: the state of the whole application lives inside the store.
So to start playing with Redux we should create a store for wrapping up the state.
Move into your React development environment and install Redux:
1 | npm i redux --save-dev |
Create a directory for the store:
1 | mkdir -p src/js/store |
Create a new file named index.js
in src/js/store
and finally initialize the store:
1 | // src/js/store/index.js |
createStore is the function for creating the Redux store.
createStore takes a reducer as the first argument, rootReducer in our case.
You may also pass an initial state to createStore. But most of the times you don’t have to. Passing an initial state is useful for server side rendering. Anyway, the state comes from reducers.
So what does exactly a reducer do?
In Redux reducers produce the state. The state is not something you create by hand.
Armed with that knowledge let’s move on to our first Redux reducer.
¶React Redux tutorial: getting to know Redux reducers
While an initial state is useful for SSR, in Redux the state must return entirely from reducers.
Cool but what’s a reducer?
A reducer is just a Javascript function. A reducer takes two parameters: the current state and an action (more about actions soon).
The third principle of Redux says that the state is immutable and cannot change in place.
This is why the reducer must be pure. A pure function is one that returns the exact same output for the given input.
In plain React the local state changes in place with setState. In Redux you cannot do that.
Creating a reducer is not that hard. It’s a plain Javascript function with two parameters.
In our example we’ll be creating a simple reducer taking the initial state as the first parameter. As a second parameter we’ll provide action. As of now the reducer will do nothing than returning the initial state.
Create a directory for the root reducer:
1 | mkdir -p src/js/reducers |
Then create a new file named index.js
in the src/js/reducers
:
1 | // src/js/reducers/index.js |
I promised to keep this guide as simple as possibile. That’s why our first reducer is a silly one: it returns the initial state without doing anything else.
Notice how the initial state is passed as a default parameter.
In the next section we’ll add an action to the mix. That’s where things will become interesting.
¶React Redux tutorial: getting to know Redux actions
Redux reducers are without doubt the most important concept in Redux. Reducers produce the state of the application.
But how does a reducer know when to produce the next state?
The second principle of Redux says the only way to change the state is by sending a signal to the store.This signal is an action. “Dispatching an action” is the process of sending out a signal.
Now, how do you change an immutable state? You won’t. The resulting state is a copy of the current state plus the new data.
That’s a lot to know.
The reassuring thing is that Redux actions are nothing more than Javascript objects. This is what an action looks like:
1 | { |
Every action needs a type property for describing how the state should change.
You can specify a payload as well. In the above example the payload is a new article. A reducer will add the article to the current state later.
It is a best pratice to wrap every action within a function. Such function is an action creator.
Let’s put everything together by creating a simple Redux action.
Create a directory for the actions:
1 | mkdir -p src/js/actions |
Then create a new file named index.js
in src/js/actions
:
1 | // src/js/actions/index.js |
So, the type property is nothing more than a string.
The reducer will use that string to determine how to calculate the next state.
Since strings are prone to typos and duplicates it’s better to have action types declared as constants.
This approach helps avoiding errors that will be difficult to debug.
Create a new directory:
1 | mkdir -p src/js/constants |
Then create a new file named action-types.js
into the src/js/constants
:
1 | // src/js/constants/action-types.js |
Now open up again src/js/actions/index.js
and update the action to use action types:
1 | // src/js/actions/index.js |
We’re one step closer to have a working Redux application. Let’s refactor our reducer!
¶React Redux tutorial: refactoring the reducer
Before moving forward let’s recap the main Redux concepts:
- the Redux store is like a brain: it’s in charge for orchestrating all the moving parts in Redux
- the state of the application lives as a single, immutable object within the store
- as soon as the store receives an action it triggers a reducer
- the reducer returns the next state
What’s a Redux reducer made of?
A reducer is a Javascript function taking two parameters: the state and the action.
A reducer function may have a switch statement (but I prefer using if).
The reducer calculates the next state depending on the action type. Moreover, it should return at least the initial state when no action type matches.
When the action type matches a case clause the reducer calculates the next state and returns a new object. Here’s an excerpt of the code:
1 | // ... |
The reducer we created in the previous section does nothing than returning the initial state. Let’s fix that.
Open up src/js/reducers/index.js
and update the reducer as follow:
1 | import { ADD_ARTICLE } from "../constants/action-types"; |
We’re not done yet! With the spread operator we can make our reducer even better:
1 | import { ADD_ARTICLE } from "../constants/action-types"; |
In the example above the initial state is left utterly untouched.
The initial articles array doesn’t change in place.
The initial state object doesn’t change as well. The resulting state is a copy of the initial state.
There are two key points for avoiding mutations in Redux:
- Using concat(), slice(), and …spread for arrays
- Using Object.assign() and …spread for objects
The object spread operator is still in stage 3. Install Object rest spread transform to avoid a SyntaxError Unexpected token when using the object spread operator in Babel:
1 | npm i --save-dev babel-plugin-transform-object-rest-spread |
Open up .babelrc
and update the configuration:
1 | { |
Redux protip: the reducer will grow as your app will become bigger. You can split a big reducer into separate functions and combine them with combineReducers
In the next section we’ll play with Redux from the console. Hold tight!
¶React Redux tutorial: Redux store methods
This will be super quick, I promise.
I want you to play with the brower’s console for gaining a quick understanding of how Redux works.
Redux itself is a small library (2KB). The Redux store exposes a simple API for managing the state. The most important methods are:
- getState for accessing the current state of the application
- dispatch for dispatching an action
- subscribe for listening on state changes
We will play in the brower’s console with the above methods.
To do so we have to export as global variables the store and the action we created earlier.
Create src/js/index.js
and update the file with the following code:
1 | import store from "../js/store/index"; |
Open up src/index.js
as well, clean up its content and update it as follows:
1 | import index from "./js/index" |
Now run webpack dev server (or Parcel) with:
1 | npm start |
head over http://localhost:8080/ and open up the console with F12.
Since we’ve exported the store as a global variable we can access its methods. Give it a try!
Start off by accessing the current state:
1 | store.getState() |
output:
1 | {articles: Array(0)} |
Zero articles. In fact we haven’t update the initial state yet.
To make things interesting we can listen for state updates with subscribe.
The subscribe method accepts a callback that will fire whenever an action is dispatched. Dispatching an action means notifying the store that we want to change the state.
Register the callback with:
1 | store.subscribe(() => console.log('Look ma, Redux!!')) |
To change the state in Redux we need to dispatch an action. To dispatch an action you have to call the dispatch method.
We have one action at our disposal: addArticle for adding a new item to the state.
Let’s dispatch the action with:
1 | store.dispatch( addArticle({ name: 'React Redux Tutorial for Beginners', id: 1 }) ) |
Right after running the above code you should see:
1 | Look ma, Redux!! |
To verify that the state changed run again:
1 | store.getState() |
The output should be:
1 | {articles: Array(1)} |
And that’s it. This is Redux in its simplest form.
Was that difficult?
Take your time to explore these three Redux methods as an exercise. Play with them from the console:
- getState for accessing the current state of the application
- dispatch for dispatching an action
- subscribe for listening on state changes
That’s everything you need to know for getting started with Redux.
Once you feel confident head over the next section. We’ll go straight to connecting React with Redux!
¶React Redux tutorial: connecting React with Redux
After learning Redux I realized it wasn’t so complex.
I knew how to access the current state with getState.
I knew how to dispatch an action with dispatch
I knew how to listen for state changes with subscribe
Yet I didn’t know how to couple React and Redux together.
I was asking myself: should I call getState within a React component? How do I dispatch an action from a React component? And so on.
Redux on its own is framework agnostic. You can use it with vanilla Javascript. Or with Angular. Or with React. There are bindings for joining together Redux with your favorite framework/library.
For React there is react-redux.
Before moving forward install react-redux by running:
1 | npm i react-redux --save-dev |
To demonstrate how React and Redux work together we’ll build a super simple application. The application is made of the following components:
- an App component
- a List component for displaying articles
- a Form component for adding new articles
(The application is a toy and it does nothing serious other than displaying a list and a form for adding new items. Nonetheless it’s still a good starting point for learning Redux)
¶React Redux tutorial: react-redux
react-redux is a Redux binding for React. It’s a small library for connecting Redux and React in an efficient way.
The most important method you’ll work with is connect
What does react-redux’s connect do? Unsurprisingly it connects a React component with the Redux store.
You will use connect with two or three arguments depending on the use case. The fundamental things to know are:
- the mapStateToProps function
- the mapDispatchToProps function
What does mapStateToProps do in react-redux? mapStateToProps does exactly what its name suggests: it connects a part of the Redux state to the props of a React component. By doing so a connected React component will have access to the exact part of the store it needs.
What does mapDispatchToProps do in react-redux? mapDispatchToProps does something similar, but for actions. mapDispatchToProps connects Redux actions to React props. This way a connected React component will be able to dispatch actions.
Is everything clear? If not, stop and take your time to re-read the guide. I know it’s a lot to learn and it requires time. Don’t worry if you don’t get Redux right know. It will click sooner or later.
In the next section we’ll finally get our hands dirty!
¶React Redux tutorial: App component and Redux store
We saw that mapStateToProps connects a portion of the Redux state to the props of a React component. You may wonder: is this enough for connecting Redux with React? No, it’s not.
To start off connecting Redux with React we’re going to use [Provider[(https://github.com/reactjs/react-redux/blob/master/docs/api.md#provider-store).
Provider is an high order component coming from react-redux.
Using layman’s terms, Provider wraps up your React application and makes it aware of the entire Redux’s store.
Why so? We saw that in Redux the store manages everything. React must talk to the store for accessing the state and dispatching actions.
Enough theory.
Open up src/js/index.js
, wipe out everything and update the file with the following code:
1 | import React from "react"; |
You see? Provider wraps up your entire React application. Moreover it gets the store as a prop.
Now let’s create the App component since we’re requiring it. It’s nothing special: App should import a List component and render itself.
Create a directory for holding the components:
1 | mkdir -p src/js/components |
and a new file named App.js
inside src/js/components
:
1 | // src/js/components/App.js |
Take moment and look at the component without the markup:
1 | import React from "react"; |
then move on to createing List.
¶React Redux tutorial: List component and Redux state
We have done nothing special so far.
But our new component, List, will interact with the Redux store.
A brief recap: the key for connecting a React component with Redux is connect.
Connect takes at least one argument.
Since we want List to get a list of articles it’s a matter of connecting state.articleswith the component. How? With mapStateToProps.
Create a new file named List.js
inside src/js/components
. It should look like the following:
1 | // src/js/components/List.js |
The List component receives the prop articles
which is a copy of the articles
array. Such array lives inside the Redux state we created earlier. It comes from the reducer:
1 | const initialState = { |
Then it’s a matter of using the prop inside JSX for generating a list of articles:
1 | {articles.map(el => ( |
React protip: take the habit of validating props with PropTypes
Finally the component gets exported as List. List is the result of connecting the stateless component ConnectedList with the Redux store.
A stateless component does not have its own local state. Data gets passed to it as props
Still confused? I was too. Understanding how connect works will take some time. Fear not, the road to learn Redux is paved with “ah-ha” moments.
I suggest taking a break for exploring both connect and mapStateToProps.
Once you’re confident about them head over the next section!
¶React Redux tutorial: Form component and Redux actions
The Form component we’re going to create is a bit more complex than List. It’s a form for adding new items to our application.
Plus it is a stateful component.
A stateful component in React is a component carrying its own local state
A stateful component? “Valentino, we’re talking about Redux for managing the state! Why on earth would you give Form its own local state??”
Even when using Redux it is totally fine to have stateful components.
Not every piece of the application’s state should go inside Redux.
In this example I don’t want any other component to be aware of the Form local state.
And that’s perfectly fine.
What does the component do?
The component contains some logic for updating the local state upon a form submission.
Plus it receives a Redux action as prop. This way it can update the global state by dispatching the addArticle action.
Create a new file named Form.js
inside src/js/components
. It should look like the following:
1 | // src/js/components/Form.js |
What can I say about the component? Besides mapDispatchToProps and connect it’s standard React stuff.
mapDispatchToProps connects Redux actions to React props. This way a connected component is able to dispatch actions.
You can see how the action gets dispatched in the handleSubmit method:
1 | // ... |
Finally the component gets exported as Form. Form is the result of connecting ConnectedForm with the Redux store.
Side note: the first argument for connect must be null
when mapStateToProps is absent like in the Form example. Otherwise you’ll get TypeError: dispatch is not a function
.
Our components are all set!
Update App to include the Form component:
1 | import React from "react"; |
Install uuid with:
1 | npm i uuid --save-dev |
Now run webpack(or Parcel) with:
1 | npm start |
and head over to http://localhost:8080
You should see the following working POC:
Nothing fancy but still useful for showing React and Redux at work!
The List component on the left is connected to the Redux store. It will re-render whenever you add a new item.
Whoaaa!
¶React Redux tutorial: wrapping up
I hope you’ll learn something from this guide. I tried my best to keep things as simple as possibile. I would love to hear your feedback in the comments below!
Redux has a lot of boilerplate and moving parts. Don’t get discouraged. Pick Redux, play with it and take your time to absorb all the concepts.
I went from zero to understanding Redux by small steps. You can do it too!
Also, take your time to investigate why and if you should use Redux in your application.
Either way think of Redux as an investment: learning it is 100% worthwile.
¶React Redux tutorial: Redux DevTools
You will find the interesting tool from here.
It’s very useful for inspect redux concept like Action, State, and can always replay the actions!