I have App.js that looks like this:
import ChildComponent from "./ChildComponent";
import { useState, useMemo, useCallback } from "react";
export default function App() {
const [pageTitle, setPageTitle] = useState("");
const [anotherProp, setAnotherProp] = useState(1);
const handleInputChange = useCallback(
(e) => {
setPageTitle(e.target.value);
},
[pageTitle]
);
const handleIncrement = useCallback(() => {
setAnotherProp(anotherProp + 1);
}, [anotherProp]);
return (
<div className="App">
<ChildComponent title={pageTitle} handleInputChange={handleInputChange} />
<div>
{anotherProp}
<input
type={"button"}
value={"Increment Count"}
onClick={handleIncrement}
/>
</div>
</div>
);
}
The child component looks like this:
function ChildComponent({ title, handleInputChange }) {
console.log("Child Component renders");
return (
<>
<input type="text" onChange={handleInputChange} />
<h1>{title}</h1>
</>
);
}
export default ChildComponent;
Since I have used useCallBack
I expect that when I click on the button to increment count, my child component should remain unaffected and not re-render. But my child component still re-renders.
Can you help me understanding why?
3
Answers
That is the standard behaviour of React. It will rerender its children when the parent component rerenders, even if the child’s props didn’t change. In this case, your parent is rerendering as its state is updating (the
anotherProp
counter).If you want to prevent a particular component from rerendering when its props remain unchanged, you can use
React.memo()
by wrapping yourChildComponent
in it, eg:With this, React won’t rerender your
ChildComponent
when its props remain unchanged.On a side note, the
[pageTitle]
dependency for your firstuseCallback()
hook is unnecessary, and can instead just be[]
as your callback does not use this state value inside of it.Another version of answer. Combination of useCallback and useMemo
App.js
Child.js
Hope, this helps.
The issue is with the dependency array in the useCallback for handleInputChange. You have pageTitle as a dependency, which causes the handleInputChange function to be recreated whenever pageTitle changes.
So Remove pageTitle from the dependency array to prevent unnecessary recreations, and it should work as expected.