Why You Should Learn Redux for React
What is Redux?
Today, we’ll take a look at the benefits of using Redux with React. Redux is a widely used cross-platform JavaScript library, used for managing application state.
Redux follows two core concepts:
Single Source of Truth
Single source of truth means instead of having multiple components managing state, Redux utilizes a singular application state for the entire application, called the Store.
Immutability
Immutability essentially means instead of modifying/changing the state object directly, we create a new state when the store updates.
The Three Parts of Redux
Store
Application state, called Store, follows the core concept ‘Single Source of Truth,’ meaning there is only one state for the entire application — held in one place: the Store. The Store can be accessed easily from any component in the application.
Actions
Actions are JavaScript objects that are dispatched to the Reducer (mentioned below). Actions must at least consist of a type
which usually describes what action is being performed. It’s common to add some type of payload
as well.
An example of a simple Action:
{type: ADD_USER , username: 'a username', password: 'a password' name: 'a name'}
Note: username
and name
are both payloads
. Commonly, payloads
are descriptively named.
Action Creators
Action Creators are functions that can accept parameters, and then dynamically generate/return an action (which is a JavaScript Object).
An example of an Action Creator:
function addUser(username, name, password){
return {type: ADD_USER, username: username, password: password, name: name}
}
Reducers
Reducers are functions that dictate how the application state will change and then return the new, updated, state. When an action is dispatched, it goes to the Reducer.
Let’s take a look at a relatively simple Reducer:
./reducers/userReducer.jsexport default function manageUsers(state = {
users: [],
newUser: {
username: '',
password: '',
name: ''
}
}, action){
switch (action.type) {
case ADD_USER:
return {...state, newUser: action.newUser }
case GET_USERS:
return {...state, users: action.users}
default:
return state;
}
};
When the ADD_USER
action is dispatched, the Reducer will return a new version of the current state (...state
) along with the newUser
object consisting of a username
, password
, and name
.
Let’s see how userReducer
and the GET_USERS
action works with these Action Creators below:
./actions/user.jsimport axios from 'axios'export const axiosFetchUsers = (users) => {
return dispatch => {
axios.get('http://localhost:3000/api/users')
.then(response => {
dispatch(getUsers(response.data))
})
.catch(e => console.log(e))
}
}export function getUsers(users) {
return { type: GET_USERS, users: users }
}
First, axiosFetchUsers
is called upon, it makes a fetch call to the backend, then getUsers
is dispatched with the parameter: response.data
(users index).
At this point, getUsers
action creator dispatches GET_USERS
with the payload being an index of user objects.
Finally, the userReducer
returns a new version of the current state (...state
)along with the new users
array of user objects.
Benefits of Redux
Dynamic Data-Flow
Redux is extremely useful for larger applications with many components.
Without Redux, a larger React application’s data flow between components can quickly become a complicated web of parent-child relationships, with little-to-no flexibility.
While manageable for smaller applications with fewer components, the standard React data-flow propagating from parent to child, can quickly become overwhelmingly complicated to manage all the individual components’ states.
With Redux, it’s all kept in the Store, simplifying the management of state significantly. Instead of having the strict flow of data propagating from parent to child components, the Redux’s Store can be easily accessed globally from any component.
Not only that but debugging and tracking state changes is much easier thanks to Redux’s intuitively simple data-flow.
Reusability — Dynamic Components
Standard React components can be very difficult to reuse as they’re usually linked closely with the root component, as the data-flow of each component’s state is tightly linked to the application’s specific parent-child relationship hierarchy.
Luckily, Redux reduces the aforementioned complexity as its globally accessible, meaning your components can be reused much easier.
Essentially Redux allows you to keep your state independent from your components. This independence gives you the flexibility to be able to build dynamic & reusable components with ease.
Conclusion
I hope this short article inspired you to look into Redux and start implementing it into your React apps.
While the learning curve may seem a bit steep at first, I’ve found that as I felt more comfortable using Redux, I found myself strongly preferring it to the standard React data-flow.
I find that having the ability to dynamically access the centralized state — independent from the actual components — makes managing state much more intuitive, and takes the headache out of having a complex component hierarchy.
Thanks to Redux’s flexibility, I find myself making applications that I would’ve never attempted before learning Redux.
Great Resources
React-Redux official site + docs
Official React binding for Redux, with docs & a quick start guide.
The only introduction to Redux (and React-Redux) you’ll ever need
This is a fantastically written post diving into what I touched on in much more detail. One of the best resources I’ve found for learning React-Redux.
The Advantages of Using Redux along with React
Another informative article, looking at the advantages of utilizing Redux with React.