Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid useless rerender using useReducer([state,dispatch]) and useContext?

When using multiple useReducers every component using a part of the state rerenders.

import React, { useContext } from 'react'
import Store from '../store'
import { setName } from "../actions/nameActions"

const Name = () => {
    const { state: { nameReducer: { name } }, dispatch } = useContext(Store)
    const handleInput = ({ target: { value } }) => { dispatch(setName(value)) }
    console.log('useless rerender if other part (not name) of state is changed'); 
    return <div>
        <p>{name}</p>
        <input value={name} onChange={handleInput} />
    </div>
}

export default Name;

How to avoid this useless rerendering?

like image 791
Verhulstd Avatar asked May 29 '19 20:05

Verhulstd


People also ask

Does useReducer trigger Rerender?

Quick summary ↬ In a React component, useState and useReducer can cause your component to re-render each time there is a call to the update functions.

Does useContext re-render?

A component calling useContext will always re-render when the context value changes. If re-rendering the component is expensive, you can optimize it by using memoization.

How do you prevent the re-rendering in React?

1. Memoization using useMemo() and UseCallback() Hooks. Memoization enables your code to re-render components only if there's a change in the props. With this technique, developers can avoid unnecessary renderings and reduce the computational load in applications.

How do I use useReducer and useContext?

Instead of passing the props down through each component, React Context allows you to broadcast props to the components below. The useReducer hook is used for complex state manipulations and state transitions. … useReducer is a React hook function that accepts a reducer function, and an initial state.


1 Answers

If useState or useReducer state changes, the component is updated, there is no way to prevent this in the component itself.

Re-render should be prevented in child component that depends on partial state, e.g. by making it pure:

const NameContainer = () => {
    const { state: { nameReducer: { name } }, dispatch } = useContext(Store)
    return <Name name={name} dispatch={dispatch}/>;
}

const Name = React.memo(({ name, dispatch }) => {
    const handleInput = ({ target: { value } }) => { dispatch(setName(value)) }
    return <div>
        <p>{name}</p>
        <input value={name} onChange={handleInput} />
    </div>
});

NameContainer can be rewritten to a HOC and serve the same purpose as Redux connect, to extract needed properties from a store and map them to connected component props.

like image 127
Estus Flask Avatar answered Nov 08 '22 12:11

Estus Flask