A React application can share multiple points of data across components. In many cases managing the data shared can become a complex task.
Redux is a library for managing and updating application state. It provides a centralized “store” for state that is shared across your entire application, with rules ensuring that the state can only be updated in a predictable fashion using events called “actions”.
Redux works well with applications that have a large amount of global state
that is accessed by many of the application’s components. The goal of Redux is to provide scaleable and predictable state management.
In Redux, a store is a container that holds and manages your application’s global state.
The store
is the center of every Redux application. It has the ability to update the global state and subscribes elements of an application’s UI to changes in the state. Accessing the state should never be done directly and is achieved through functions provided by the store
.
In Redux, an action is a plain JavaScript object that represents an intention to change the store’s state. Action objects must have a type
property with a user-defined string value that describes the action being taken.
Optional properties can be added to the action object. One common property added is conventionally called payload
, which is used to supply data necessary to perform the desired action.
/*Basic action object for a shopping listthat removes all items from the list*/const clearItems = {type: 'shopping/clear'}/*Action object for a shopping listthat adds an item to the list*/const addItem = {type: 'shopping/addItem',payload: 'Chocolate Cake'}
A reducer (also called a reducing function) is a plain JavaScript function that accepts the store’s current state
and an action
and returns the new state
.
Reducers calculate the new state
based on the action it receives. Reducers are the only way the store’s current state
can be changed within a Redux application. They are an important part of Redux’s one-way data flow model.
/*A reducer function that handles 2 actionsor returns the current state as a default*/const shoppingReducer = (state = [],action) => {switch (action.type) {case "shopping/clear":return [];case "shopping/addItem":return [...state,action.payload];default:/*If the reducer doesn't careabout this action type, returnthe existing state unchanged*/return state;}}
When performing an immutable update on a mutable value, such as an array or an object, the value’s contents are copied into a new array or object and this copy is mutated.
Some strategies for ensuring immutable updates are:
...
) to obtain copies of objects and arraysstate = ['sleep', 'work', 'relax']const newState = {...state, 'read'}/*newState = ['sleep', 'work', 'relax', 'read']*/state = {location: 'North Pole',temperatures: [-10, -14, -9, -18]}const newState = {...state,temperatures: [...state.temperatures,-22, -17]}/*newState = {location: 'North Pole',temperatures: [-10, -14, -9, -18, -22, -17]}*/
Reducers must follow these three rules:
These rules help support Redux’s scaleable and predictable state management. Some common behaviors to avoid inside reducers are network requests, generating random numbers, and using asynchronous functions.
Redux follows a one-way data flow model:
Store → View → Actions → Store