Reputation: 21
I need to change the checkbox checked status, but useCallback re-renders component a lot of times. I don't understand how it works. I've read a lot of materials about it.
const AppealsList = () => {
const [isFiltered, setFiltered] = React.useState(false);
console.log('rerender');
const changeCheckBox = useCallback(() => {
setFiltered(!isFiltered);
}, [isFiltered]);
return (
<div className={classNames('appeals')}>
<div className={classNames('appeals__filter')}>
<input
checked={isFiltered}
className={classNames('appeals__input')}
type="checkbox"
readOnly={true}
/>
<label
onClick={changeCheckBox}
className={classNames('appeals__filter-label')} />
</div>
</div>
);
};
Amount of re-renders:
Upvotes: 1
Views: 1431
Reputation: 39222
This is because you have written your callback with a dependency on isFiltered
so it will change every time you click. It works best when it does not depend on the very state that the callback is changing.
To create a toggle function that does not constantly change, have it call setState with a function so that it can compute new state from previous state, taking advantage of functional state updates offered by useState
:
const changeCheckbox = useCallback(() => {
setFiltered(currentValue => !currentValue);
}, []); // look no dependencies!
You can read about functional state updates (deriving new state from current state) here: https://reactjs.org/docs/hooks-reference.html#functional-updates
If the new state is computed using the previous state, you can pass a function to setState. The function will receive the previous value, and return an updated value.
Upvotes: 1
Reputation: 870
setCallback is used to memoize functions so if you have heavy functions that require a lot of processing you don't have to processes the same inputs twice. For example if you had a function that adds two numbers and you give it 4 and 3 then it runs the function and memorizes that when you input 4 and 3 into the function the result is 7. So next time it is passed 4 and 3 instead of processing the result it uses the memorized result.
While useCallBack is used to memorize functions, useEffect is used to prevent unnecessary rerenders. I think in this case you are wanting to use the useEffect Hook?
Upvotes: 0