I pass the click handler to the child component and it causes re-rendering every time when a parent component changes. Can’t figure out how to stop it. Without the "handleClick" prop the child component doesn’t re-render.
function SubComponent({ handleClick }) {
console.log("component render");
return <div onClick={handleClick}>SubComponent</div>;
}
const MemoizedSubComponent = memo(SubComponent);
export default function App() {
console.log('app render')
const [test, setTest] = useState(1);
const onHandleClick = () => {
console.log(1)
};
const increment = ()=>{
setTest(test+1)
};
return (
<><button onClick={increment}>Increment {test}</button>
<MemoizedSubComponent
handleClick={onHandleClick}
/></>
);
}
Working code is here: https://codesandbox.io/s/zen-https-6hl04z
How to test:
- click the "IncrementN" button in the App component and see the console: it will say "rerender component" every time when you click.
- if you remove or comment the handleClick={onHandleClick} line in the App, there is no re-rendering every time but only when some data props change like tab.
How to prevent this re-rendering?
2
Answers
React will re-render your component when it detects changes in props.
You have defined a function
testoClick
in App, and passed it toTodoList
.testoClick
is created every timeApp
renders, and so React detects that props has changed, and will re-renderTodoList
. This is expected.You can use the
useCallback
hook to memoise thetestoClick
handler.useCallback
will return the same object reference so long as the dependencies have not changed.By returning a memoized
testoClick
, React will not detect any changes in props, and therefore will not re-renderTodoList
Since you are using an arrow method directly, the method is not memoized. This would create a new instance every time the component is rendered (with new props object with a new reference even though it looks the same on code).
Wrapping the testoClick method with an useCallback hook would help resolve your problem.
Tip for optimization: Move all the inline arrow methods to useCallback wrapped methods. Example below: