I am coming form angular and getting used to react. I was reading the docs on event handling and stumbled upon this:
class LoggingButton extends React.Component {
handleClick() {
console.log('this is:', this);
}
render() {
// This syntax ensures `this` is bound within handleClick
return (
<button onClick={() => this.handleClick()}>
Click me
</button>
);
}
}
the docs then say:
" The problem with this syntax is that a different callback is created each time the LoggingButton renders. In most cases, this is fine. However, if this callback is passed as a prop to lower components, those components might do an extra re-rendering. We generally recommend binding in the constructor or using the class fields syntax, to avoid this sort of performance problem."
I don't have access to constructor as I am using hooks. What should I do?
I prepared a quick demo. The structure is App > [CompA > Comp B]. There is a button in component B that increments count and the state of the count is kept in App. Through props the callback is delegated from App through Comp A to comp B. Whenever I click the count button in Comp B, it re-renders the entire Comp A. This can be verified by the random number generation. It's fine for this component but wouldn't this be a problem in a large project?
Now imagine I have a quiz app and I keep score in the main App. If someone selects right answer inside a Question component I would like to keep a count of that in the main App. Doing it this way would re-render any intermediate components. What's the pattern I should follow?
Use the useCallback
hook. It'll return the same function as long as its dependencies remain the same.
const callback = useCallback(()=> { /* do something */ }, [/* dependencies */])
The dependencies work the same as the useEffect
hook.
From your demo, <CompA onCount={() => setCount(count + 1)} />
is perfectly fine, Dan Abramov said as much.
Parent re-renders will render their children, so if the count state is in the parent, the children will be re-rendered. That's perfectly fine. React is built to do that very quickly.