Connecting React with Redux
Tags: react, redux, javascript, webdev
Published: 2020-01-18 16:02:13

---
title: Connecting React with Redux
published: true
description: Connecting Redux with React app
tags: react, redux, javascript, webdev
canonical_url: https://irian.to/blogs/connecting-react-with-redux
---

This is part two of my Redux mini-series. You can find the first part [here](https://dev.to/iggredible/redux-101-48kc). I *highly* recommend reading it first if you are new to Redux. 

- [*Part one*: Understanding Redux](https://dev.to/iggredible/redux-101-48kc)
- [*Part two*: Setting up Redux and React app](https://dev.to/iggredible/redux-101-connecting-react-with-redux-195m) (👈 We're here)

In my first post, we learned conceptually what Redux does and why we needed Redux. Let's jump into the code!

# Setup

The repository can be found [here](https://github.com/iggredible/basic-redux). I will go through with the code.

```
git clone https://github.com/iggredible/basic-redux.git
cd basic-redux
npm i
npm run start
```

If you want to start from scratch, you can use [create-react-app](https://github.com/facebook/create-react-app). Also install [redux](https://www.npmjs.com/package/redux) and [react-redux](https://www.npmjs.com/package/react-redux).

# Code breakdown

I will go over Redux action and reducer. Then I will cover how to connect Redux to our app. Store and initialState will also be covered by the end of the code walkthrough! 👍

Most of our Redux files are inside `src/javascripts`. Inside you will see `actions/` and `reducers/`. Let's go to actions first.

# Actions

Inside `actions/`, we see two files: `index.js` and `types.js`. Let's talk about types first.

Types are constants. A Redux action is a JS object. This object tells our reducer what to do with our states. A typical action might look like this:

```
{
  type: CHANGE_BUTTON_COLOR,
  color: 'red'
}
```

or very simple one like this:

```
{
  type: TOGGLE_IS_HIDDEN,
}
```

Every action needs a type. The [convention](https://redux.js.org/basics/actions/#actions) for type that Redux uses is that it has to be string, all caps, and snake case.

We store our types inside `types.js`

```
export const ADD_NOTE = "ADD_NOTE"
export const DELETE_NOTE = "DELETE_NOTE"
```

You may wonder, "why would I want to go out of my way to create a file full of constants? Why can't I just type the types as I go? "

Valid enough. The reasons are: 

1. Prevent typos
2. Keep track of all available types
3. Modularity

When your app grows, your types will grow. It is normal to have hundreds of types in a project and with that, chances of misspelling a word increases. Using a dedicated file for constants reduces the chance of misspelling. 

Additionally, if a new developer joins your project few years down the road, that dev can just look at `types.js` and get a good idea what functionalities your app can do!

Lastly, when your app grows to have hundreds of types, you can split them for modularity. You can have something like `actions/types/customer.js` for all your customer related action types and `actions/types/merchandise.js` for all your merchandise related action types.


Now let's go where the actions are (pun intended 🤓)

```
// actions/index.js
import {ADD_NOTE, DELETE_NOTE} from "./types";
let id = 0;

export const addNote = notes => {
  id++;
  return {
    type: ADD_NOTE,
    notes: {...notes, id: id}
  }
}

export const deleteNote = id => {
  return {
  type: DELETE_NOTE,
  id
  }
}
```

We have two actions: one to add a note and one to delete a note. If you notice, they both return a plain JS object. Forewarning, it needs to at least have a `type`. Actions are set of instructions that will be sent to our reducer. 

Think of it like a grocery list. Sometimes my wife would ask me to grab fruits from the store. In this case, she would give me an action that looks like this:

```
{
  type: PICKUP_GROCERY,
  items: ['mangoes', 'rice', 'cereal']
}
```

Remember, an action does not do anything yet. It is simply an instruction. The execution happens in reducer.

When we sends off an action to reducer, in Redux' term, we call it *dispatching*. 

Here we have two actions: on to add a note and one to delete it. In our simple note app, we would give our submit button the `addNote` dispatcher and the `delete` button next to each note `deleteNote` dispatcher.

Let's see how action gets executed in reducer!

# Reducer

Inside `src/reducers/index.js`, we see:

```
import {ADD_NOTE, DELETE_NOTE} from "../actions/types";

const initialState = [
    {title: "First Note", id: 0}
  ]

function rootReducer(state = initialState, action){
  switch(action.type){
    case ADD_NOTE:
      return [...state, action.notes]

    case DELETE_NOTE:
      return state.filter(note => note.id !== action.id)

    default:
      return state;
  }
}

export default rootReducer;
```

Let's go through it top to bottom.


The first line is self-explanatory:

```
import {ADD_NOTE, DELETE_NOTE} from "../actions/types";
```

It imports the constants from types.


```
const initialState = [
    {title: "First Note", id: 0}
  ]
```

This is our initial state. Every time we run our app, we see that after page loads, we always have one note called "First Note". This is the initial state. Even after you delete it, if you refresh the page, redux resets, our states go back to initial state, and you'll see "First Note" again.

This is the main functionality of our reducer function:

```
function rootReducer(state = initialState, action){
  switch(action.type){
    case ADD_NOTE:
      return [...state, action.notes]

    case DELETE_NOTE:
      return state.filter(note => note.id !== action.id)

    default:
      return state;
  }
}

```

Our reducer takes two arguments: state and action. As default value, we give it initialState. 

Note the switch case:

```
  switch(action.type){
    case ADD_NOTE:
      return [...state, action.note]

    case DELETE_NOTE:
      return state.filter(note => note.id !== action.id)

    default:
      return state;
  }
```

Conventionally, reducers use switch case to decide what to execute depending on the action type it receives. 

If we pass it `ADD_NOTE` type, it finds a match and returns: `[...state, action.note]`. 

I am not doing `return state.push(action.note)`, but instead `[...state, action.note]`. This is important. If I had done `.push()`, I would be changing the state stored in redux. We do *not* want that. Our reducer needs to be a [pure function](https://redux.js.org/basics/reducers/). 

A pure function is function that: does not produce side effect and given the same input, will always return the same output. Further explanation is outside the scope of this tutorial, but you can check [this](https://www.freecodecamp.org/news/why-redux-needs-reducers-to-be-pure-functions-d438c58ae468/) and [this]([source](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-pure-function-d1c076bec976)) out!). Just know that your reducer must never change the original state. 

# Connecting Redux to our React app

Phew, we finished with actions and reducers. We need to connect our Redux to React. Go to `src/index.js`:

```
import React from 'react';
import ReactDOM from 'react-dom';
import App from "./App"
import {createStore} from 'redux';
import {Provider} from 'react-redux';
import rootReducer from './javascripts/reducers'

const store = createStore(rootReducer);

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)


```
At minimum you need:
- a reducer function (in this case, `rootReducer`)
- `createStore` from redux and `Provider` from `react-redux`, instantiated using `createStore()`
- Wrap our app with `Provider` 👆 and `store`.

That's it! Now our `<App />` is connected to redux. Finally, let's make things work.

# React + Redux

I am not going to go through each line of code in App.js, but I will touch on the important things:

```
import {connect} from "react-redux";

...

const App = connect(mapStateToProps, mapDispatchToProps)(ConnectedApp)

export default App;
```

We need to *connect* our React component (named `ConnectedApp`) to our store. We will use `{connect}` from `react-redux` library and connect it with `mapStateToProps` and `mapDispatchToProps`. This `App` then gets exported. 

You might wonder what do `mapStateToProps` and `mapDispatchToProps` do 🧐?


```
const mapStateToProps = state => {
  return {
    notes: state
  }
}

const mapDispatchToProps = dispatch => {
  return {
    addNote: note => dispatch(addNote(note)),
    deleteNote: note => dispatch(deleteNote(note))
  }
}
```

`mapStateToProps` and `mapDispatchToProps`, as the name suggests, maps our redux states and redux actions to be used as props in our app.

In `mapStateToProps`, we receive `state` argument - this `state` is all our Redux states. In effect, we can now view all our states as notes props! Inside our app, we can see our states with `this.props.notes`. 

Which is what we did. Inside render, you'll see:

```
render() {
  const { notes } = this.props;
  ...
```

If it wasn't mapped in `mapStateToProps`, you would get undefined. Our `this.props.notes` is now our Redux states! How cool is that? This is how our we access the states.

The same goes with our dispatchToProps. Guess what this does:

```
const mapDispatchToProps = dispatch => {
  return {
    addNote: note => dispatch(addNote(note)),
    deleteNote: note => dispatch(deleteNote(note))
  }
}
```
Some of you might even guessed it. Let's compare our `mapDispatchToProps` with our actions:


```
// App.js
...
const mapDispatchToProps = dispatch => {
  return {
    addNote: note => dispatch(addNote(note)),
    deleteNote: note => dispatch(deleteNote(note))
  }
}
...

// actions/index.js
...
export const addNote = notes => {
  id++;
  return {
    type: ADD_NOTE,
    notes: {...notes, id: id}
  }
}

export const deleteNote = id => ({
  type: DELETE_NOTE,
  id
})
```

They are one and the same! When we send our actions to reducer, it is said that we are "dispatching" them. We are making our redux `addNote` and `deleteNote` actions available to our app as `this.props.addNote` and `this.props.deleteNote` through `mapDispatchToProps`.

Here you can see both `deleteNote` and `addNote` being used:

```
  handleSubmit(e) {
    const {addNote} = this.props;
    const {title} = this.state;
    e.preventDefault();
    addNote({title})  // dispatches addNote action
    this.setState({title: ''})
  }

  handleDelete(id) {
    const {deleteNote} = this.props;
    deleteNote(id);  // dispatches deleteNote action
  }

```

This is how our app executes redux action.

# Testing your knowledge

Here's a challenge: try adding new action to update the notes (try not to use google immediately! Spend about 30-60 minutes struggling. That's how you'll get better)

Or another challenge: try adding completed: true/false status to indicate whether a note has ben completed. If true, change the color to light gray.

# Conclusion

There you have it folks. React/ Redux. Although this is only the beginning, I hope you now understand better why we use Redux, what Redux does, and how Redux works with React.

Once you master Redux basics, I'd suggest looking up Redux middleware, especially [redux-saga](https://redux-saga.js.org/) to handle async data.

Thanks for reading. Appreciate you spending your time reading this article. 

If you have any questions, feel free to ask!