How to prevent unnecessary re-renders when using context in React?
Asked Answered
F

0

6

In my app, I want to pass the global store of my application to the child components via context. For the sake of an example, I have created 2 child components namely Child1 and Child2, and passing increment and decrement counter functions along with the corresponding counter values to them. Child1 is responsible for incrementing counter1 and child2 for decrementing counter2. When I am invoking the increment/decrement function in the components, the other component is uselessly getting re-rendered along with the parent. How can I prevent this from happening?

Please find the above use-case here

Below is the code for the same,

App.js

import React, { useState, useCallback } from 'react';
import './style.css';
import { UserContext } from './Context.js';
import Child1 from './Child1';
import Child2 from './Child2';

export default function App() {
  const [counter1, setCounter1] = useState(0);
  const [counter2, setCounter2] = useState(0);
  const IncrementCounter = useCallback(
    () => setCounter1((prevState) => prevState + 1),
    [setCounter1]
  );
  const DecrementCounter = useCallback(
    () => setCounter2((prevState) => prevState - 1),
    [setCounter2]
  );
  const store = {
    child1: {
      counter1,
      IncrementCounter,
    },
    child2: {
      counter2,
      DecrementCounter,
    },
  };
  console.log('App re-rendering');
  return (
    <UserContext.Provider value={store}>
      <Child1 />
      <Child2 />
    </UserContext.Provider>
  );
}

Child1.js

import React, { useContext } from 'react';
import { UserContext } from './Context.js';

const Child1 = () => {
  const store = useContext(UserContext);
  const { child1 } = store;
  console.log('Child1 Re-rendering');
  return (
    <div>
      <p>{`Counter1 value : ${child1.counter1}`}</p>
      <button onClick={child1.IncrementCounter}>Increment</button>
    </div>
  );
};

export default React.memo(Child1);

Child2.js

import React, { useContext } from 'react';
import { UserContext } from './Context.js';

const Child2 = () => {
  const store = useContext(UserContext);
  const { child2 } = store;
  console.log('Child2 Re-rendering');
  return (
    <div>
      <p>{`Counter2 value : ${child2.counter2}`}</p>
      <button onClick={child2.DecrementCounter}>Decrement</button>
    </div>
  );
};

export default React.memo(Child2);

Context.js

import React from 'react';

const UserContext = React.createContext();

export { UserContext };
Fountain answered 21/12, 2021 at 19:31 Comment(1)

© 2022 - 2024 — McMap. All rights reserved.