Step 1 out of 3

Install Redux dependencies

begin our file structure

create our first action

We need to install two packages. In your terminal enter npm install --save react-redux redux

Now in your /src/ directory create a new folder, redux in this folder we will contain all our Redux files and activities in one central place.

disclaimer: majority of the Redux community do not create a redux directory. They tend to create the redux directories(ie. actions, reducers) right into the /src/ directory. But I feel it helps me keep all Redux related data in one place to quickly navigate.

Now let’s create our first action.

An action is how your global state is changed. You can think of an action as an event that is fired off (from a button click, when a component mounts).

Actions are payloads of information that send data from your application to your store.

We’ll create an action that will add a new player to our list, and the action is fired when we click on the Add button.

Create a new directory /src/redux/actions now in here let’s create a new file and name it player.js . Open your player.js file and create the first action:

export const ADD_PLAYER = "ADD_PLAYER"; export const addPlayer = player => ({

type: ADD_PLAYER,

data: player

});

The first line will allow us to use this action type in other files (which you will see in the next step). Additionally not using a string literal will make bugs easier to find. For example, If we mistype the action type in any files we’ll receive a clear undefined error.

Beneath the action type is our action. Doesn’t look too complicated right? Plain ‘ol JavaScript function.

Takes the player we want to add, we input our action type and then we’ll send it over to the next step in our assembly line. The object we are returning will make much more sense in our next reducer step.

Before wrapping step 1, let’s test this new action we created in our app.

Head into your /src/app.js file and add import { addPlayer } from “./redux/actions/player.js”; beneath import React,...

Now overwrite what’s in the handleClick function with

handleClick = () => {

console.log(addPlayer(this.state.textInput));

};

Now npm start your app, type anything into the text input and click Add. In your developer console you should now see what an action looks like,

{type: “ADD_PLAYER”, data: “Alexis Sanchez”}

data:”Alexis Sanchez”

type:”ADD_PLAYER”

This is what our Action looks like! This is what we’re sending to Step 2 to determine what to do.

As you can see the Action is just logging and sending what happened. It’s up to our next step to determine what to do.

This step we setup our environment, created our first action and logged it to the console.

Here is our code as of step 1:

Step 2 out of 3

Create our reducers

Actions describe the fact that something happened, but don’t specify how the application’s state changes in response. This is the job of reducers.

Let’s create our reducer.

Stop and contemplate over the word reducer, this will help visualize this step. What we are doing is based off the action type ( ADD_PLAYER ) we will be REDUCING to the correct path to take to modify the state.

In your redux directory create a new folder and name it reducers . Now in your reducers directory create 2 files, 1) index.js , 2) player.js .

The directory structure should look like this so far:

-redux

--actions

---player.js

--reducers

---index.js

---player.js

Let’s first open reducers/index.js and enter the following:

import { combineReducers } from "redux";

import player from "./player"; export default combineReducers({

player

});

In our case we only have one reducer that will handle our actions, the player reducer.

Imagine you had a large app with different actions coming from different places from your applicaiton. For example, signing in actions, changing default language actions, adding new player actions…

Instead of having 1 large reducer file, you can break them into their own their own respective file.

As your app grows more complex, you’ll want to split your reducing function into separate functions, each managing independent parts of the state. The combineReducers helper function turns an object whose values are different reducing functions into a single reducing function you can pass to createStore .

The point of this file is to combine all our reducers. In our case just the single player.js reducer. The only time you would need to revisit this file is to add a new reducer you have created.

Now access our next file, reducers/player.js to begin writing our first reducer.

import { ADD_PLAYER } from "../actions/player";

const initialState = {

people: [{ id: 1, name: "Mesut Ozil" }]

}; function returnNameObj(name) {

return {

id: Date.now(),

name

};

} const reducer = (state = initialState, action) => {

switch (action.type) {

case ADD_PLAYER:

return {

...state,

people: [...state.people, returnNameObj(action.data)]

};

default:

return state;

}

}; export default reducer;

Remember the action type we created in our actions/player.js file? This is where we are importing it, again to help with typo bugs.

We have an helper function returnNameObj whose job is to create our new player object that we can append to our people array of objects (see initial state). The function returns a JavaScript object with the name of the new player we’re adding and also generating a unique ID using Date.now(). In the real world I’d recommand using something like UUID.

Then we are going to create our initial state, this is exactly how we setup our initial state in /src/App.js in our component state, but now we’re going to bring the initial state into redux.

Now the reducer function itself, we take in two arguments

Our initial state (which we created above) The action that is coming in from our actions/player.js file

When we take the action, we delegate which changes to the state we are going to make based on the action type. Remember step 1 was to capture which event was fired off, now we are determining what to do based off that action.

For example, if the action that came into the reducer had an action type of ADD_PLAYER then we are going through a plain JavaScript switch statement to determine which changes to the state we should make.

Things you should never do inside a reducer: Mutate its arguments

Hence why when we hit our ADD_PLAYER case, we first copy our existing state then go on to create our new state. Never modifying the current state. The 3 things happening, when an action.type matches a switch case:

Copy our existing state Add our new player that came with the the action — remember data: player when we were creating our actions? The action holds action.type and action.data And finally return this to our store who holds our application state (we’ll be going over store in the next step)

Here is the code for the two new files,

Step 3 out of 3

Create our store

In the previous sections, we defined the actions that represent “what happened” and the reducers that update the state according to those actions.

The Store is the object that brings them together. The store has the following responsibilities: Holds application state; Allows access to state via getState() ; Allows state to be updated via dispatch(action) ; … read more

We’re almost there! We now need to create our store. The glue to bring together the actions, reducers, and state.

The good thing about the store file is, you create it once and never really have to revisit much.

In the redux directory create a new file name it store.js with the following:

import { createStore } from "redux";

import reducer from "./reducers"; const store = createStore(reducer);

export default store;

createStore Creates a Redux store that holds the complete state tree of your app.

There should only be a single store in your app.

Simple right? We are using the createStore function, and passing in the reducer function whose in charge of updating our state depending on which action it was sent. Steps, 1–2–3.

One last piece before we’re done with Redux, we need to wrap our React app with our Redux store which is quite literally 2 lines of code.

Open /src/index.js start by importing Provider at the top:

import { Provider } from "react-redux";

Then our Redux store,

import store from “./redux/store”;

Now we need to wrap our <App /> with the provider so we can access our Store from any of our Components we create, you can visualize this step as we’re sending the data down to all our components to access.