Using React-Redux for dispatching actions to update the store
A conceptual example using actions and reducers
As a CTO at A&M Consulting, I help my company to keep its competitive edge and to stay technologically sustainable. However, in terms of technology, A&M Consulting is still at a pre-seed stage.
The company has been successfully running for many years, and as part of the Digital Transformation Strategy, we are now in the process to launch our first product.
In such circumstances, the company’s CTO must be a practical engineer that should be ready to build the digital product architecture without third-party help and remains the main specialist to implement it.
I’ve had to make decisions about package management, bundling, linting, transpiling, automated testing, and so on. One key decision I had to face was whether to use or not Redux in our current Front solution and…believe me, I took the right decision 🙃.
Redux
To this day, Redux follows three fundamental principles:
- single source of truth
- state is read-only
- changes to the state are only done by pure functions
There are three building parts: actions, store, and reducers. I am going to show you only one single component here based on React.
That component is a box containing some relevant information, which will be shown as a part of the dashboard (main view of the app) on the top view.
Actions
Simply put, actions are events. They are the only way you can send data from your application to your Redux store. Let’s see the getAlert1 action;
import axios from ‘axios’;import { API_HOST } from ‘app/constants’;export const GET_ALERT1 = ‘[ANALYTICS DASHBOARD APP] GET ALERT1’;export function getAlert1(user) { let alert1 = axios.get(`${API_HOST}/user/${user.data.id_gestor}/clients_centers_per_user?rol=${user.role}`, {headers: { Authorization: `Bearer ${user.token}` }});return dispatch => alert1 .then(response => { if (response.status === 200) { dispatch({ type: GET_ALERT1, payload: response.data.rows[0] }); } else { dispatch({ type: GET_ALERT1, payload: null }); }}).catch(error => { console.log(error); dispatch({ type: GET_ALERT1, payload: error.response });});}
Reducers
Reducers are pure functions that take the current state of an application, perform an action, and return a new state. These states are stored as objects, and they specify how the state of an application changes in response to an action sent to the store. So, the GET_ALERT1 reducer should be:
import * as Actions from '../actions';const initialState = { data: null};const alertReducer = (state = initialState, action) => { switch (action.type) { case Actions.GET_ALERT1: return { ...state, alert1_data: { ...action.payload } }; default: return state; }};export default alertReducer;
As pure functions, they do not change the data in the object passed to them or perform any side effect in the application. Given the same object, they should always produce the same result.
Store
The store holds the application state. There is only one store in any Redux application. You can access the state stored, update the state, and register or unregister listeners via helper methods.
Then, in my Dashboard.js file, I’ll use the useSelector() Redux function to access to the store:
The Redux store has a method called dispatch
. The only way to update the state is to call store.dispatch()
and pass in an action object. The store will run its reducer function and save the new state value inside:
In this point, we got the data into the rawResponseAlert1 variable. Now, all what you need to do is to pass to the component the data as props.
Let’s take a look at the Alert component:
Conclusion
One major benefit of Redux is to add direction to decouple “what happened” from “how things change.” However, you should only implement Redux if you determine your project needs a state management tool.