reactjsreact-hooksmemousecallback

React useCallback() function in Parent is only working fine with Child if React.memo is used, without it not working


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);

Solution

  • 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.