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';
index.js will contain the actions for the application.
import {
ADD_CLIENT
}from './types';
export const addClient = (client) => {
return {
type: ADD_CLIENT,
payload: client
};
};
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,
});
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;
}
}
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>,
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,
};
}
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);
connect
The connect function connects a React component to a Redux store
export default connect(mapStateToProps, {
//actions
addClient,
})(ClientForm);
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 ");
}
}
The complete code is here
Top comments (0)