Redux Cheatsheet
Tags: redux, react, tutorial
Published: 2020-04-16 10:14:58

This article will lay out the installation, setup, and usage of Redux in a React App. There will also be an overview of reducers, seeing as the Redux store requires one upon creation.

## Installation

Install the Redux and React-Redux library in your project's main directory:

```bash
npm install redux react-redux
```

## Setup

Below are key imports for Redux and React-Redux's main functionality:

```javascript

import { createStore } from 'redux';
...
import { Provider } from 'react-redux';
...
import { connect } from 'react-redux'

```

Inside of your main JS file for rendering your app (i.e. index.js) we need to:

1. Import our necessary functions and components
2. Create a store
3. Implement the Provider component
4. Render our app

```javascript

// Standard React imports
import React from 'react';
import ReactDOM from 'react-dom'

// Redux related imports
import { createStore } from 'redux';
import { Provider } from 'react-redux'

// Reducer to manage the store's data
import reducer from './reducer'

// Main application component
import App from './App'


// Create a store for our state
const store = createStore(reducer);


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

```

## Usage

#### Understanding

React-Redux allows the developer to _connect_ a React component  to a Redux store. This connection needs to define the communication from and to the store.  

- From - state needed for the component as props
- To - functions that define the intended changes to state (action)

If a component only needs one form of communication, set the other type to null.

Inside of your React component, we need to do three steps to connect:

 1. Import functions that define needed actions
 2. Create a function that defines how state is mapped to props
 3. Connect and export the component

#### Implementation

Let's say we have an app that handles RSVP'ing to a wedding. One of many requirements would be for a guest to register their dining preference.

To satisfy this requirement, we need some component to:

- Display a known list of all food preferences
- Get user input for their preferred food
 
```javascript

// necessary non-Redux imports for component
import React from 'react'

// Redux related imports
import { setPreference } from './actions'

const mapStateToProps = ( state ) => {
	return {
		preferences: state.preferences,
		currentGuest: state.currentGuest
	}
};

// React component setup with state as props
const GuestPreference = ( props ) => {
   return (
      <div className='container'>
         <h2>Please set your preference {props.currentGuest.name}</h2>
         {
            props.preferences.map( item => {
               <div onClick={ () => props.setPreference(item) }>
                  { item }
               </div>
            })
         }
      </div>
   )
};

// Export and connect the component to the store
export default connect( mapStateToProps, { setPreference })(GuestPreference)

```

## Reducers

#### Understanding

A **reducer** is a function that manages state in a *pre-defined* way. This is the behavior that allows Redux to be consistent. 

When creating a reducer, two things are expected:

1. The structure of state will be consistent
2. Interaction with state is defined through an object.

That structure is often referred to as **initial state**. For example:

```javascript

const initialState = {
	/* example application state */
	guests: [],
	currentGuest: {
		name: "Stephen",
		...
		preference: ""
	},
	preferences: ["Steak", "Fish", "Salad"]
}

```

That object is referred to as an **action** with a standard structure of:

```javascript

{
	type: /* String defining how to manage */,
	payload: /* any javascript value */
}

```

#### Implementation

Let's stick with the RSVP app idea for consistency. This app has pre-defined behavior of setting the guest's food preference. 

As such, we need to create a function that returns an action our reducer can interpret and reliably know what to do with the data. For instance:

```javascript

/* inside of a file 'actions.js' */

// create and export types for our actions
export const SET_PREFERENCE = "SET_PREFERENCE";

// create functions that return pre-defined actions
export const setPreference = ( name ) => {
	return {
		type: SET_PREFERENCE,
		payload: name
	}
};

```

Now there is a standard for how our reducer should manage data. Let's create the reducer.

```javascript

/* inside the file reducer.js */

// import the types this reducer supports
import { SET_PREFERENCE } from './actions'

// create the reducer, please note the javascript shorthand
function reducer(state = initialState, action) {
	// work off of the type
	switch(action.type) {
		// type for setting preference
		case SET_PREFERENCE:
			return {
				// keep the state we don't touch
				...state, 
				currentGuest: {
					 // keep the nested state of current guest
					...state.currentGuest,
					// set the preference from the action
					preference: action.payload
				}
			};
		
		// default statement for types not yet supported
		default:
			return state;
	}
}

// export the reducer
export default reducer;

```

Please note how the reducer does not directly manipulate the state but rather creates a *copy* and uses it instead.