0

Parent Component

The parent component contains input which on change sets the state "local" and a button which on click takes this "local" state's value and sets it to "sendLocal"

Functions

  1. changehandler : triggers on input type change.

  2. sendLocalValue : takes "local" value puts it into "sendLocal" variable triggers on button click.

  3. sendValue : this memoized function with dependeny "sendLocal" is passed on as a prop in child component triggers once the child is rendered.

    import React, { useState, useCallback } from "react";
    import ChildComponent from "./ChildComponent";
    
    function ParentComponent() {
      const [local, setLocal] = useState();
      const [sendLocal, setsendLocal] = useState();
    
      const changehandler = (e) => {
        console.log("parent");
        setLocal(e.target.value);
      };
    
    const sendLocalValue = () => {
            setsendLocal(local);
          };
    
      const sendValue = useCallback(() => {
        return sendLocal;
      }, [sendLocal]);
    
    
    
      return (
        <>
          <input type="text" onChange={changehandler} defaultValue={local} />
          <button onClick={sendLocalValue}>send</button>
          <ChildComponent getValue={sendValue} />
        </>
      );
    }
    
    export default ParentComponent;
    

Child Component

getValue prop calls the memoized "sendValue" function of parent which returns the value of sendLocal.

Problem

Everything works fine,the child component renders only when the "sendLocal" value changes on button click but if i remove React.memo() in child both the component render on input type change even with useCallback() used, why?

    import React, { useEffect, useState } from "react";

function ChildComponent({ getValue }) {
      console.log("child");
    
      return <div>child's {getValue()}</div>;
    }

export default React.memo(ChildComponent);
Sujith Sandeep
  • 1,185
  • 6
  • 20
fahad saleem
  • 616
  • 6
  • 8

2 Answers2

2

There is a general misconception that React components rerender when props or state change. while this is partially true, can lead to misunderstoods: a react component rerenders when its state changes or when its parent rerenders (because its state changed or because its parent rerendered, and so on).

So this means that every time ParentComponent rerenders, all its (non memoized) children will rerender.

To avoid this, you can use React.memo or React.PureComponent.

You can verify that by removing React.memo and not passing any props to the ChildComponent. Even with no props, it will rerender every time its parent rerenders.

Nahuel
  • 141
  • 2
  • so you're saying i must use React.memo for there is to be a memoized function? or can i not use useCallback() without it? – fahad saleem Feb 14 '21 at 16:45
  • 1
    A component can also re-render when a context provider it consumes re-renders. – Patrick Roberts Feb 14 '21 at 16:46
  • 1
    @fahadsaleem if you want to prevent ChildComponent from rerendering, then yes you need to use React.memo + React.useCallback to memoize the function. – Nahuel Feb 14 '21 at 17:26
0

when the parent re-renders, the whole props object for the child is created as a new object, which leads to the child re-render. it does not matter that you have memoized all the different individual props, you have to memoize the component itself so that it does not re-render when the whole props object changes.

In this case, it also means that you still have to memoize the function as well as the child component, because React.memo only does a shallow comparison of individual props.

gaurav5430
  • 12,934
  • 6
  • 54
  • 111