DEV Community

Violeta
Violeta

Posted on

Using Redux with React

The purpose of this post is to explain in a simple way how to use redux in a react application.

React is component based, every component can share properties between other components from parent to child using the props system, the props are immutable data a component cannot change.

Every component manage its own state, the state contains information that is relevant to one component at a
specific time, has an initial default value and its value eventually varies usually in response to a user action.
Every time the value of state changes the components are updated immediately.

Sometimes you need to share information between components at same level or from child to parent, not from parent to child, and change values in response a user action, to solve this you can use Redux.

Redux is a state management library, it makes complex applications easier to handle.

Case to solve

I have two compoments: ClientForm and ClientList, when I enter a new Client I need validate if the new client already exist in my client list and if not, add the client to the list, these are separate components and are at the same level.

How to solve

It seems like we need a shared client list between the components, we can't pass it through props because components are at the same level and props are immutable so we can't add new values to the list.

Redux provides a repository(store) outside the components where we can manage the state and is responsible for keeping the information updated and providing it to the component that requests it.

Implementing Redux

First create a react app, go to the root folder and install redux and react-redux libraries with:

npm install redux react-redux

redux is the redux library and react-redux makes react and redux work together

In the src folder add folders for: actions, reducers and components

Redux Components

Action

An Action is event that describes something that happened in the application, in this case add client or list clients. Every action has a type and a payload.

In the actions folder create files: types.js and index.js

types.js contains the types of actions we will use, these are just constants to prevent any typing error

export const ADD_CLIENT = 'ADD_CLIENT';
Enter fullscreen mode Exit fullscreen mode

index.js will contain the actions for the application.

import {
    ADD_CLIENT   
}from './types'; 

export const addClient = (client) => {     
    return { 
        type: ADD_CLIENT, 
        payload: client 
    };
};
Enter fullscreen mode Exit fullscreen mode

Reducer

A Reducer is a function that handles events based on the received action type and decides how to update the state if necessary.

In the reducers folder create files clientReducer.js and index.js
clientReducer will contain the actions to handle events from clients

index.js contains a special function which combines all reducers in your app

import { combineReducers } from 'redux';
import clientReducer from './clientReducer';

export default combineReducers({
    clientReducer,

});
Enter fullscreen mode Exit fullscreen mode

in clientReducer we have the functions in response to the action:

import {
    ADD_CLIENT,
}from '../actions/types'; 


export default (state = []  , action) =>{ 
    switch(action.type){

        case ADD_CLIENT:               
            return [...state,  action.payload] ;  

        default:
            return state;
    }
}
Enter fullscreen mode Exit fullscreen mode

Store

Store is a centralized repository where the app state lives.

Provider

Provider is the one that provides values in the state to the other components of the application.

We will configure the provider in src/index.js:

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

const store = createStore(reducers);

ReactDOM.render(
  <Provider store={store}>
    <ThemeProvider theme={theme}>
      <App />
    </ThemeProvider>
  </Provider>,
Enter fullscreen mode Exit fullscreen mode

You need to import Provider, createStore and your reducers to create store and pass the store to the provider.

mapStateToProps

indicates how to transform the state of the store into the props that you want to pass to a component, you define this function in the componentent where you need use the state

const mapStateToProps = (state) =>{   
  return { 
    clientList: state.clientReducer, 
  };
}
Enter fullscreen mode Exit fullscreen mode

in this case we have a clienteReducer which has an array of clients, in mapStateToProps we indicate that the array will referenced as clientList in the props

//searching if the client exists 
    const val  = props.clientList.filter(
        cli => cli.name == client.name);
Enter fullscreen mode Exit fullscreen mode

connect

The connect function connects a React component to a Redux store

export default connect(mapStateToProps, {
  //actions
  addClient,  
})(ClientForm); 
Enter fullscreen mode Exit fullscreen mode

Once we have mapStateToProps and connect function in our component we can call through the props values from the store or send values to the store

For example, adding a new client we validate if the client exists in the client list (getting the cliente list from the store) and if not exists add new client ( setting the cliente to the store and updating the list with the new values for the ClientList conent)

const addCliente = () =>{    
    //searching if the client exists 
    const val  = props.clientList.filter(
        cli => cli.name == client.name);
    //if not exists add client to list 
    if(val.length === undefined || val.length === 0){
        props.addClient(client);
        setClient({name: '', email: ''});
    }else{
        alert("Client already exists ");
    }
  }
Enter fullscreen mode Exit fullscreen mode

The complete code is here

Alt Text

Top comments (0)