Redux for Buddies Pt2: writing to state
Tags: redux, react, reactredux, state
Published: 2019-05-29 21:14:21

---
title: Redux for Buddies Pt2: writing to state
series: Redux for Buddies
published: true
description: 
tags: redux, react, react-redux, state
---

Where we last left off, we had a general understanding of the Redux loop. We understood that **containers** provide access to our `store`, which we selectively use to hydrate our components' `props` via `mapStateToProps`.

As a quick refresher, here's what the general loop looks like:

> **store** (state) -*defines*-> **frontend** -*triggers*-> **event handler** (or other functionality) -*sends data/signal (action) to*-> **reducer** -*updates*-> **store (state)**


For convenience's sake, we'll take the code we've written and replace the `otherComponent` we were rendering with a `<p>` tag that will display our `userCount`. With that modification, here's our code so far: 

```javascript
import React, { Component } from 'react';
import { connect } from 'react-redux';
const mapStateToProps = store => ({
    users: store.users.userCount // store looks like: {'userCount':5}
})

const mapDispatchToProps = dispatch =>({
    //we'll fill this in and explain it later!
})

class DisplayUsers extends Component{
    constructor(props){
        super(props);
    }
}
render(){
    <p>{this.props.users}</p>
}
export default connect(mapStateToProps, mapDispatchToProps)(DisplayUsers)
```

Now, to get state updates to work, we need to send data from the frontend. We'll start with that. Remember `mapDispatchToProps`?

Well, `dispatch` is what allows our frontend to send data up to the `store`. Let's imagine that we have a button that we want to click to add 1 to our `usercount`. 

```javascript
import React, { Component } from 'react';
import { connect } from 'react-redux';
const mapStateToProps = store => ({
    users: store.users.userCount // store looks like: {'userCount':5}
})

const mapDispatchToProps = dispatch =>({
    //we'll fill this in and explain it later!
})

class DisplayUsers extends Component{
    constructor(props){
        super(props);
    }
}
render(){
  <div>
    <p>{this.props.users}</p>
    <button onClick={/* some function */}>add user</button>
  </div>
}
```

So, in order to mutate our state, we need to `dispatch` an `action` to our `store`. Let's start by talking about what an `action` is, starting with how they're created.

## Action Creators / Actions

An Action Creator is a function. It takes a single argument in, and returns an object which we refer to as an `action`. An `action` is just an object that has two properties on it: `type` and `payload`.

Here's what an action creator might look like:

```javascript
import * as types from '../constants/actionTypes'

export const addUser = (payload) =>({
  type: types.ADD_USER,
  payload: payload  
})
```
As you can see, `addUser` returns an object that looks like this: `{type: types.ADD_USER, payload: /* whatever payload we give it */}`, which is the `action` that it is creating.

So, what is a `type`? and what data might we want to have in our `payload`?

### Action Types

A `type` is really just a string that we're importing from our `actionTypes` file. By convention, the names of our actions are capitalized.

Basically, there are different types of state updates that we would like our `reducers` to 
handle, and our `type` determines which one to use. We'll get into our `reducers` a little further down, but, for now, we'll look at what our `actionTypes.js` file might have inside of it:

```javascript
export const ADD_USER = 'ADD_USER';
```

It's really just a string with a few conventions applied to it.

So, as far as why we'd store that string in a variable instead of just typing it in directly, it has to do with the reason that Redux exists in the first place: scale.

At scale, there are a few benefits to using action types. From Dan Abramov's own words:

> * It helps keep the naming consistent because all action types are gathered in a single place.

> * Sometimes you want to see all existing actions before working on a new feature. It may be that the action you need was already added by somebody on the team, but you didn’t know.

> * The list of action types that were added, removed, and changed in a Pull Request helps everyone on the team keep track of scope and implementation of new features.

> * If you make a typo when importing an action constant, you will get undefined. This is much easier to notice than a typo when you wonder why nothing happens when the action is dispatched.

it's total overkill for a project this scale, but so is Redux. That being said, we'll get to our `payload`

### Payload

`payload` is the other property on our `action`. This is the actual data that we'll send to our `reducers`. (if our `action` needs to provide data at all- increasing our user count by 1 doesn't require any info other than action type).

We'll need to talk about `reducers` to really understand `actions`, but we'll talk about how we send `actions` to our `reducers` first.

## Back To mapDispatchToProps

So, we've got an `actionCreator`, which returns an `action`, which has a `type` and `payload`. It's called `addUser`. Let's import it and send it to our `store`!


```javascript
import React, { Component } from 'react';
import { connect } from 'react-redux';

import * as actions from '../actions/actions';

const mapStateToProps = store => ({
    users: store.users.userCount 
})

const mapDispatchToProps = dispatch =>({
    addUser: (e)=>dispatch(actions.addUser(e))
})

class DisplayUsers extends Component{
    constructor(props){
        super(props);
    }
}
render(){
  <div>
    <p>{this.props.users}</p>
    <button onClick={this.props.addUser}>add user</button>
  </div>
}

export default connect(mapStateToProps, mapDispatchToProps)(DisplayUsers)
```

There are four changes we made. 
* we're importing `actions`, as we defined above. 
* we're adding a property to the object returned by `mapDispatchToProps`, which is a function that takes in something called `dispatch`.
* `mapDispatchToProps` returns an object whose properties and methods will be made available on our `this.props` by virtue of the next thing:
* We use `connect` to make the properties on `mapStateToProps` and the methods on `mapDispatchToProps` available on our `this.props` by running a function on all of those things and exporting the results.

`dispatch` and `store` are provided by Redux, by virtue of the `connect` method we're importing from it. `dispatch` ultimately accepts an `action`, but in this case we're using an action creator to generate that action, providing similar benefits to using constant action types.

Now that we've done all of this, we can finally hit the `reducers`.

## Reducers

In our implementation of Redux, we'll have an `index.js` file that will serve as an entrypoint for our reducers- that is, we'll import all of our reducers to `index` and have redux decide which ones to use. We'll also have a `usersReducer.js` where we'll write our functionality.

`index.js` will look like this:

```javascript
import { combineReducers } from 'redux';
import usersReducer from './usersReducer';
const reducers = combineReducers({
  users: usersReducer
})

export default reducers
```

First, a note about the key name of `users` that we're using to store `usersReducer`. If you look at our `mapStateToProps`, we're grabbing `store.users.userCount`. This is why/how we shape our `store`, which is just an object that holds objects that hold the state associated with their respective reducer.

So, what does our `usersReducer` look like?

`usersReducer` should be a function that takes in two parameters, one of which is the `state` contained by our `store`, and the other of which is an `action` (such as the ones we've created with our action creators and dispatched to the store by virtue of our `dispatch`). The body of our `usersReducer` should essentially be a big switch statement that returns an object, which will comprise the new `state` of our `store`, thus completing the process.

Let's write our `usersReducer`. We'll create some initial state, and have our function fall back to returning it if nothing happens.

```javascript
import * as types '../constants/actionTypes';
const initialState = {
  userCount: 0
}

const usersReducer = (state = initialState, action) =>{
  switch (action.type){
    default:
      return state;
  }
}
```

The `type` of an `action` will determine what part of the `switch` gets fired off. Let's add a case for when we receive `ADD_USER` as our `type`.

```javascript
import * as types '../constants/actionTypes';
const initialState = {
  userCount: 0
}

const usersReducer = (state = initialState, action) =>{
  switch (action.type){
    case types.ADD_USER:{
      const userCount = state.userCount + 1;
      return {
        ...state,
        userCount
      }
    }
    default:
      return state;
  }
}
```

let's break down what we did here.

First, we're creating a `const` for `userCount`. We're doing this to keep our code organized, which is more of a factor when we're trying to create a new `state` that has multiple properties that differ from the old one. Next, we're simply returning a new object that spreads our previous state, then overwrites the old value of `userCount` with a new one.

We do this partially to merge our old `state` into our new `state`, and partially so that we generate an entirely new `state` object. In generating a new `state` object, we ensure that React recognizes that we've changed our `state` and appropriately rerenders its components. (If you need more info on why we do this, I'll write a bit about primitive vs composite data types in JS and link here later)

Anyways, now that we've handled our `reducer`, that's the end of the whole Redux cycle. We've written to our `store`!

## Let's walk it through

1. a user clicks "add user"
2. "add user" fires off a version of `addUser` which has had `dispatch` mapped to it by `mapDispatchToProps`
3. `addUser` takes in the `action` returned by our `ADD_USER` action creator and triggers our `reducers`
4. our `reducers` find a matching `case` for `ADD_USER`, then generates a new `state` object.
5. the new `state` object gets passed back to our frontend components by `mapStateToProps`

And that's the flow of this particular Redux implementations. There are plenty of other ways to do it, and the value of it is only really seen at scale. Thanks for following along!