Introduction
In the
previous article, we have reviewed how to use useReducer() hook in ReactJs and what are the benefits of it. Now, in this article, we will be learning about using multiple useReducer() hooks in a component having a similar state followed by using the useContext() hook along with the useReducer() hook.
Using multiple useReducer() hook
Whenever there is a requirement of using the same state along with multiple variables, we can use useReducer() hook. Let’s see the demo.
Create MathMultipleReducer.js component,
- import React, { useReducer } from 'react'
-
- const initialState = 0
- const reducer = (state, action) => {
- switch (action) {
- case 'addition':
- return state + 1
- case 'subtraction':
- return state - 1
- case 'reset':
- return initialState
- default:
- return state
- }
- }
-
- function MathMultipleReducer() {
- const[countOne,dispatchOne] = useReducer(reducer, initialState)
- const[countTwo,dispatchTwo] = useReducer(reducer, initialState)
- return (
- <div>
- <div> Counter One - {countOne}</div>
- <button onClick={() => dispatchOne('addition')}>Addition</button>
- <button onClick={() => dispatchOne('subtraction')}>Subtraction</button>
- <button onClick={() => dispatchOne('reset')}>Reset</button>
- <div> Counter Two - {countTwo}</div>
- <button onClick={() => dispatchTwo('addition')}>Addition</button>
- <button onClick={() => dispatchTwo('subtraction')}>Subtraction</button>
- <button onClick={() => dispatchTwo('reset')}>Reset</button>
- </div>
- )
- }
-
- export default MathMultipleReducer
The output of it will display as below.
When clicking on Addition, it will update the first counter.
On clicking on Subtract, it will update the second counter.
useReducer() hook with the useContext() hook
SO far we have seen how to use useReducer() hook in ReactJs and how we can use a single state along with multiple variables. We have also seen how to locally manage state. Now using useReducer() along with the useContext() hook allow to Share state or props between components i.e) creating the global component. So, for this, we will be creating 3 components that will share a single state component among 3 of them - UserName.js,UserGender.js, and UserAge.js.
Let’s add a code in App.js.
- import React, { useReducer } from 'react';
- import './App.css';
- import UserName from './components/UserName';
- import UserGender from './components/UserGender';
- import UserAge from './components/UserAge';
-
- const initialUser = {
- Name: '',
- Age: '',
- Gender: ''
- }
-
- const reducer = (state, action) => {
- switch (action.type) {
- case 'UserName':
- return {
- Name: action.Name,
- Gender: '',
- Age: ''
- }
- case 'UserAge':
- return {
- ...state,
- Age: action.Age
- }
- case 'UserGender':
- return {
- ...state, Gender: action.Gender
- }
- default:
- return state
- }
- }
-
- export const UserContext = React.createContext()
-
- function App() {
- const [user, dispatch] = useReducer(reducer, initialUser)
-
- return (
- <div className="App">
- <UserContext.Provider value={{ user, dispatch }}>
-
- <UserName />
- {user.Name && <UserGender />}
- {user.Gender && <UserAge />}
- </UserContext.Provider>
- {
- user.Age && (
- <p>User name is <b>{user.Name}</b> having gender <b>{user.Gender}</b> of Age <b>{user.Age}</b></p>
- )
- }
- </div>
- );
- }
-
- export default App;
UserName.js,
- import React, { useState, useContext } from 'react'
- import { UserContext } from '../App'
-
- function UserName() {
- const { dispatch } = useContext(UserContext)
-
- const [userName, setName] = useState('')
-
- return (
-
- <div>
- <input type="text" placeholder="Name" value={userName} onChange={(e) => { setName(e.target.value) }} />
-
- <button type="button" onClick={() => dispatch({ type: 'UserName', Name: userName })}>Next</button>
- </div>
- )
-
- }
-
- export default UserName
UserGender.js,
- import React, { useState,useContext } from 'react'
- import { UserContext } from '../App'
-
- function UserGender() {
- const [gender, setGender] = useState('')
- const {user, dispatch } = useContext(UserContext)
- return (
- <div>
- <h2>Gender value for user {user.Name}</h2>
- <input type="text" placeholder="Gender" value={gender} onChange={(e) => { setGender(e.target.value) }} />
-
- <button type="button" onClick={() => dispatch({ type: 'UserGender', Gender: gender })}>Next</button>
- </div>
- )
- }
-
- export default UserGender
UserAge.js,
- import React, { useState,useContext } from 'react'
- import { UserContext } from '../App'
-
- function UserAge() {
- const [age, setAge] = useState('')
- const {user, dispatch } = useContext(UserContext)
- return (
- <div>
- <h2>age value for user {user.Name}</h2>
- <input type="text" placeholder="age" value={age} onChange={(e) => { setAge(e.target.value) }} />
-
- <button type="button" onClick={() => dispatch({ type: 'UserAge', Age: age })}>Submit</button>
- </div>
- )
- }
-
- export default UserAge
The output will display as below.
Add name and click on the "Next" button.
Add Gender and click on the "Next" button.
After adding all values, it will display output as above.
Summary
In this article, we have reviewed about using multiple useReducer() in a single component to use the same state for different values and using state and props among components.
You can download the source code attached along with this article. In the next article, we will be learning about fetching data from API using useReducer() hook.