Redux for Buddies 1: Reading State/Store
Tags: redux, react, reactredux
Published: 2019-02-21 07:41:53

---
title: Redux for Buddies 1: Reading State/Store
published: true
series: Redux for Buddies
description: spoiler, the dummy is me
tags: redux, react, react-redux
---

Okay, so I finished a project that made use of React and Redux. I'm pretty much a beginner at React and this is the first time I've used Redux, so if you're in a similar place as me, this writeup may be helpful. I'm going to assume that you understand the basics of React, and are able to handle basic tasks such as rendering components, creating and managing stateful components, and accessing and passing props between components.

First, let's start by talking about Redux in generalized, abstracted terms. Redux is a state management library. Where our React app might maintain 'state' in a few different places, or have to pass state down to the components that need it, Redux keeps all of our state in a centralized store, which can be accessed by our React components.

This is fairly simple in theory. You can imagine it working in a similar way to a global object, one which would maintain all of the information we needed to determine the status of our app. Components can 'see' that state and determine what they need to do, based on the information stored inside of it. Some would be able to modify the state as well. Imagine submitting a form or clicking a button and the page changing in response.

However, there is a lot of configuration that needs to be done in order to accomplish this, and much of it is done in fairly specific ways.

Here's what the general loop looks like:

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

###store

**Store** is basically an object that contains our state. As such, there are two basic operations we need to do with it:

1. read from it
2. write to it

We don't quite have enough time or space to cover doing both, so we'll talk about how to read from our **store**.

However, as a prerequisite to doing either of those things, we have to have some way that our React app can communicate with the store. React Redux provides us with this in the form of a **provider** and **containers**. 

The provider is an element that is built in to our react-redux library. we import it from react-redux and wrap our entire app in it. It will go in the render function that hangs our entire app on the DOM, like so:

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

Provider is, thus, making it possible for our app to access the store that's passed in as a 'store' property. This 'store' is a data structure created by using createStore, and giving it our reducers and (optionally) the output of a function called 'composeWithDevTools' (which allows Chrome's [Redux devtools](https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd?hl=en) to interface with the store).

As I said before, a lot of the trouble with learning Redux is just getting all of the configuration done and ensuring that all of the parts are communicating properly with one another. In fact, there's still one more piece that we need in order to read and write from our store: Our **containers**.

**containers** are not special in themselves, but in the way that we're thinking about/using react-redux, they are similar to our provider. Basically, they are the components where we're choosing to create a connection to the store, via the react-redux **connect** function.

There are pretty much two things we need to do in a container in order to read a value from our store.

1. create **mapStateToProps**
2. invoke our **connect**

###mapStateToProps

This is a function whose purpose is to act as a callback to react-redux's **connect** function. Conceptually, it defines the way that **connect** will make the state from our store available as [props on our component](https://reactjs.org/docs/components-and-props.html). It returns an object whose keys are the names of pieces of data that will be made available on the this.props object on the container. 

For instance, let's say our store looks like this: `{'userCount':5}`.


**mapStateToProps** might look something like this:
```javascript
const mapStateToProps = store => ({
    users: store.users.userCount
})
```

Through the magic of **connect** (again, a built-in react-redux function), we would be able to do this:

```javascript
console.log(this.state.users)
```
and have it log `5` to our console.

A simple container might look something like this:

```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)
```

So, if we display this component, the thing that should render out is a single p tag, with a value that we've read from our store! (specifically, store.users.userCount)

At this point you may have noticed that we're defining **mapStateToProps**, but never invoke it, and it may be unclear where exactly the returned value of the object might go or what it might do. The answer is that little function invocation at the bottom, **connect**.

###Connect

**Connect** is what makes our whole container work. It's a built-in method that we're importing from the react-redux library, and it takes two callbacks and returns a function, which we're then immediately invoking with our entire component as an argument.

What's returned out of it is a version of our component that has the values from our **mapStateToProps** available on its `this.props` object. That's what's being exported from this file, and that's what we're seeing when we import and render our component.

This may seem confusing, but this is the reason that we're able to have `<p>{this.props.users}</p>` in our component and actually have it render the value from our **store** despite having never defined `this.props.users`, and having never passed `users` as a prop to our component.

Essentially, we write the **DisplayUsers** component as if it already had access to the values that we're mapping in **mapStateToProps**, because we know that, after invoking **connect**, we're going to be dealing with a version of our **DisplayUsers** component that *does* have access to the mapped values that **mapStateToProps** handles.

Note that, once the desired bits of our state are mapped on to props on our container component, we can also pass them down to other components as we would any property.

```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(){
    <OtherComponent users={this.props.users} /> // imagine we had defined and imported some React component called OtherComponent
}
export default connect(mapStateToProps, mapDispatchToProps)(DisplayUsers)
```

In summary:

1. create a function (*mapDispatchToProps*) that specifies the data that we want to access from our store (*'usercount'*), and the label(s) that they'll have on the props object (*'users'*, accessible at *this.props.users*)
1. create a component (*DisplayUsers*) as you would any other React component, except that you're free to reference labels from **mapDispatchToProps** as if they were keys on your props object
1. call **connect** using your mapping functions and the name of your component as arguments, knowing that it will connect the mapped values with your component's properties by accessing the store. (*connect(mapStateToProps,mapDispatchToProps)(DisplayUsers)*)

I swear I'll explain **mapDispatchToProps** in the next post. As a teaser, you can know that it's similar to **mapStateToProps**, but will provide us with the necessary functionality to cause a change in our state/store, with a few intermediary steps.