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);
CodePudding user response:
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>
);
};
CodePudding user response:
So only thing you are missing is to pass a compareFunction which will tell React.Memo exact condition when to rerender the component. You can see your code working here. https://codesandbox.io/s/romantic-cherry-bv5y0?file=/src/App.js
import "./styles.css";
import React, { useState, useCallback } from "react";
const Button1 = ({ handleClick }) => {
console.log("Button - rerender");
return (
<div>
<button onClick={handleClick}>Sayacı artır</button>
</div>
);
};
const compareFunction = (prevProps, nextProps) => {
return true; //As props only have a function which we are sure doesn't change.
};
const Button = React.memo(Button1, compareFunction);
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;