Understanding React Redux

Félix Andersson
The Startup
Published in
5 min readJun 2, 2020

Redux is a library to control the state and data flow over the app. There’s a common single source of truth in the whole app (it provides consistency). The state is read-only, the only way to modify it is through a defined action, all these actions pass through a single common point where we handle them

This is a basic guide so you can look for more detailed information at React Redux Documentation whenever you want.

Index.

1. Basic Redux concepts

  • Store
  • Actions
  • Reducers

2. Basic React Redux Concepts

  • Connector
  • Provider

3. Implementation

  • Installing Packages
  • Creating a Store and implementing Provider
  • Creating the Reducer
  • Creating an Action
  • Connecting a Component

1. Basic Redux Concepts

Store

It’s where we store the whole state of the app, it’s our single source of truth. The state can only be modified as a consequence of an Action.

When we create a Store, we need to bind a Reducer to it.

Actions

When in the App there happens something where we should modify its state, it is when we use a Redux Action, it is a simple object with the needed information that is dispatched to the Reducer so it will be able to do the respective modifications to the state.

In practice, we create a function that receives information as parameters and then returns an Action object (we will call that function in a component to create an Action with the respective data), we also should create a ‘type’ property (string) in each Action object, so the Reducer may know which type of Action is receiving, thus carry out the corresponding operations.

The Action object also should contain the information that the Reducer needs to perform those operations, that information is usually sent from the component. The Reducer will receive this Action object by parameter, so the data will be easily accessed.

Reducers

It is a function that receives the current state and an Action, the returns a new state.

But BEWARE, we must create a completely new state object, so we should clone the actual state somehow, otherwise, if we modify the current state directly to return it as a new state, it will not work.

2. Basic React Redux Concepts

Connector

We use the connect() function to make a component able to read data from the Store and dispatch Actions. It allows us to insert state data fragments or “Action creator functions” to the component

connect() parameters…

1. mapStateToProps — Read state

This is a function that receives the whole state from the Store, then returns a plain object, where each property is a property that we will send to the component.

Here is where we extract data pieces that the component needs.

2. mapDispatchToProps — Modify state

This is a plain object which, like in the previous parameter, each property is a property that we will send to the component. These properties should be our “Action creator functions”, we should only pass the Actions that the component will need to dispatch its information to the Store.

Unlike the state, these Actions are not retrieved from the Store, we get them by importing them from a file where we save our Action functions.

Thereafter the component will be able to access these functions and execute them. Into the component, we can pass the parameters they need to create the Action object, then it will be automagically dispatched to the reducer

(End parameters…)

The connect() function returns a “connector function” that we will use to convert a React component to a new component with those properties bound.

~ connectorFunction(Component);

This new component is the one we should export from the file.

We usually do it as follows…

export default connect(mSP, mDP)(Component);

But how the connect function knows from which store it gets the state data?

Well, that’s when we use the React Redux Provider…

Provider

The Provider is a React component that provides a Store to all its nested components. It binds the Store state to all components connected using connect() into it.

Normally we can’t use a connected component if it is not into the Provider. We usually put the whole App into the Provider.

3. Implementation

Installing Packages

npm i redux react-redux --save

Creating a Store and implementing Provider

We will create the store and bind it to the whole App through a Provider, so we should render a <Provider> at the top level, with the entire App inside it.

We will use createStore() of Redux to create our Store, we should pass the Reducer as a parameter, and an initial state…

(…)import { Provider } from ‘react-redux’;import { createStore } from ‘redux’;import reducer from ‘./redux/reducers’;const store = createStore(reducer, initialState);ReactDom.render(<Provider store={reducer}><App/></Provider>,document.getElementById(‘root’));

Creating the Reducer

We will create a function that receives the previous state with an Action, then returns a new state based on the Action type.

const reducer = (state, action) => {switch (action.type) {case ‘LOGIN_REQUEST’:return {…state,user: action.formData}default:return state}};export default reducer;

We are using a Switch to run the respective logic depending on the Action type, then returning a modified state.

But remember, we MUST create a completely new state object to modify it, if we directly modify the actual state, it will not work.

If you have problems to clone the state object you can use this trick…

const newState = JSON.parse(JSON.stringify(state));

Creating an Action

We will create a ‘loginRequest’ Action that we will use in an example below.

Remember: In the Action object, we will specify a type (string), with the information to dispatch to the Reducer.

We will create a function to create an Action object based on the received data from a login form…

export const loginRequest = (formData) => ({type: ‘LOGIN_REQUEST’,formData});

Connecting a Component

  • Home example — Reading state
(…)import { connect } from ‘react-redux’;const Home = { categories } => {}// Extract categories prop from stateconst mapStateToProps = state => ({categories: state.categories});// We create the connector functionconst connectComponent = connect(mapStateToProps);// The connector takes the component, then returns a new one with the mapped propertiesexport default connectComponent(Home);
  • Login Example — Modifying state

Here we will use the Action function that we created above

import { connect } from ‘react-redux’;import { loginRequest } from ‘../redux/actions’;const LoginForm = ({ loginRequest }) => {const handleSubmit = () => {// This will create an Action 
// object to dispatch automatically
loginRequest(formData);}}const mapDispatchToProps = {loginRequest}export default connect(null, mapDispatchToProps)(LoginForm);

--

--

Félix Andersson
The Startup

Web Developer, passionate about making cool stuff with the computer since I was a child. Loving to learn and helping others to learn.