Search code examples
javascriptreactjsreact-hooksreact-propsusecallback

Problem with rendering object prop sent to child component


The problem is: Every time I click the button, I see "Button render" in the console. But I want to see this post only once The problem is: Every time I click the button, I see "Button render" in the console. But I want to see this post only once

import React, { useState, useCallback } from "react";
    import Button from "./Button";
    
    const UseCallback = () => {
      const [count, setCount] = useState(0);
    
      const handleClick = useCallback(() => {
        setCount((prevState) => prevState + 1);
      }, []);
    
      return (
        <div>
          <p>{count}</p>
          <Button
            deneme={{ aaa: "aaa", bbb: "bbb" }}
            handleClick={handleClick}
          ></Button>
        </div>
      );
    };
    
 export default UseCallback;


   
    import React from "react";
    
    const Button = ({ handleClick }) => {
      console.log("Button - rerender");
      return (
        <div>
          <button onClick={handleClick}>Sayacı artır</button>
        </div>
      );
    };
    
    export default React.memo(Button);

Solution

  • It is suppose to re-render since the callback is changing on render and you are passing a new object reference on each render to button. You already have React.memo but since you have a new object reference every time it's a re-rendering button.

    Try wrapping object in useMemo to keep the same reference or create a variable at top and pass it in deneme prop

    const UseCallback = () => {
      const [count, setCount] = useState(0);
    
      const handleClick = useCallback(() => {
        setCount((prevState) => prevState + 1);
      }, []);
      const deneme = useMemo(() => {
        return { aaa: "aaa", bbb: "bbb" };
      }, []);
      return (
        <div>
          <p>{count}</p>
          <Button deneme={deneme} handleClick={handleClick}></Button>
        </div>
      );
    };
    

    or

    const deneme = {
      aaa: "aaa",
      bbb: "bbb"
    };
    const UseCallback = () => {
      const [count, setCount] = useState(0);
    
      const handleClick = useCallback(() => {
        setCount((prevState) => prevState + 1);
      }, []);
      return (
        <div>
          <p>{count}</p>
          <Button handleClick={handleClick}></Button>
        </div>
      );
    };