State management is a crucial aspect of building complex applications in React. It allows you to manage and share data between different components efficiently. Let’s start with the basics:
In React, each component can have its own local state. State is an object that represents how a component should render and behave
Basics
Reducers
A reducer is simply a function that allows us to centralize state updates in a component.
useReducer(reducer, initialArg, init?)
Parameters
reducer
:- ➡️ The reducer function that specifies how the state gets updated. It must be pure, should take the state and action as arguments, and should return the next state. State and action can be of any types.
initialArg
:- ➡️ The value from which the initial state is calculated. It can be a value of any type. How the initial state is calculated from it depends on the next
init
argument.
- ➡️ The value from which the initial state is calculated. It can be a value of any type. How the initial state is calculated from it depends on the next
- optional
init
: - ➡️ The initializer function that should return the initial state. If it’s not specified, the initial state is set toinitialArg
. Otherwise, the initial state is set to the result of callinginit(initialArg)
. Syntax
Returns
useReducer
returns an array with exactly two values:
- The current state. During the first render, it’s set to
init(initialArg)
orinitialArg
(if there’s noinit
). - The dispatch function that lets you update the state to a different value and trigger a re-render.
dispatch function
The dispatch
function returned by useReducer
lets you update the state to a different value and
trigger a re-render. You need to pass the action as the only argument to the dispatch
function:
React will set the next state to the result of calling the reducer
function you’ve provided with the current state
and the action you’ve passed to dispatch
.
Dispatch with payload
Sometimes you need a given payload to be sent with your dispatch
Example2
React Context API
Context API is a built-in mechanism in React to manage state at a global level. It allows you to share data between components without having to pass props down through the entire component tree.
What is context? Context is like state, but instead of being confined to a component, it’s global to your application. It’s application-level state. This is dangerous. Avoid using context until you have to use it.
Allows sharing data without passing it down through many components in the middle
The reducer hook and the state are both ways to maintain local state in the components,
Redux
Redux is a popular state management library for React applications. It enforces a strict unidirectional data flow and provides a central store for your application’s state.
Redux is a predictable state container for JavaScript apps
Redux API
Redux is really small it simply has few methods attached to it .
- ➡️ Apply Middleware
- ➡️ Compose
- ➡️ Combine Reducers
- ➡️ Bind action creator
- ➡️ Create Store
- dispatch: ƒ dispatch(action)
- getState: ƒ getState()
- replaceReducer: ƒ replaceReducer(nextReducer)
- subscribe: ƒ subscribe(listener)
A reducer is simply a function that takes in a state, and the things that happened and only one thing comes out of it, a new state
Compose
The compose
function takes multiple functions as arguments and returns a new function that represents the composition of these functions. In Redux, it’s commonly used to apply multiple store enhancers or middleware to the store creation process.
Create Store
A function that takes a reducer and creates you main state returns you functions to interact with your tore
- dispatch: ƒ dispatch(action)
- Sends actions into the reducer to do mutations to the current state of the application
- getState: ƒ getState()
- get the state of our store
- replaceReducer: ƒ replaceReducer(nextReducer)
- Swaps out the reducer
- subscribe: ƒ subscribe(listener)
- Subscribes to the store and when something changes, then do domething!
Bind action creator
Binds an action, then returns a new object with the same keys, but each action creator is wrapped in a dispatch
call. This makes it easier to invoke the action creators directly, and the resulting functions automatically dispatch the actions.
Core Concepts
Redux is based on three core principles:
- Store: A single, immutable source of truth for your application’s state.
- Actions: Plain JavaScript objects that describe a change in the application’s state.
- Reducers: Functions that specify how the state changes in response to actions.
Actions
Synchronous Actions
Actions are plain JavaScript objects that describe events or user interactions in your application. They represent what happened and the data associated with the event. An action object typically includes two properties:
-
type
:- ➡️ A string that describes the type of action. It’s a unique identifier for the action.
-
payload
:- ➡️ An optional property that carries data related to the action. This can be any valid JavaScript value like an object, string, or number.
Here’s an example of an action object:
Actions serve as a way to communicate changes in your application, and they are dispatched to the Redux store, where reducers respond to them
Async Actions
Asynchronous API calls to fetch data from an endpoint and use the data in your application
Reducers
specify how the app’s state changes in response to actions sent to the store function that accepts state and action as arguments and returns the next state of the application
(previousState,action) => newState
Store
one store for the entire application
- It has the following responsibilities
- Holds application state
- Allows access to state via getState()
- Allow sate to be updated via Dispatch(action)
- Register listeners via subscribe(listener )
- Handle unregistering of listeners via the function returned by subscribe(listener)
Redux Store Methods
replaceReducer
Takes one reducer and replace it with another one
The Redux store exposes a replaceReducer
function, which replaces the current active root reducer function with a new root reducer function. Calling it will swap the internal reducer function reference, and dispatch an action to help any newly-added slice reducers initialize themselves:
getState
This simply gets a state
Middleware
is the suggested way to extend Redux with custom functionality Provides a third party extension point between dispatching an action, and the momenet it reaches the reducer
- We use middleware for :
- Logging,
- Crash reporting
- performing asynchronous tasks etc…