In the Reach Hooks FAQ section "How to read an often-changing value from useCallback?" there is an example:
function Form() {
const [text, updateText] = useState('');
const textRef = useRef();
useEffect(() => {
textRef.current = text; // Write it to the ref
});
const handleSubmit = useCallback(() => {
const currentText = textRef.current; // Read it from the ref
alert(currentText);
}, [textRef]); // Don't recreate handleSubmit like [text] would do
return (
<>
<input value={text} onChange={e => updateText(e.target.value)} />
<ExpensiveTree onSubmit={handleSubmit} />
</>
);
}
I was so confused:
instead of useCallback update the function each time the text change, this code move it to textRef in useEffect but isn't that the same because the callback function doesn't change but you still need 1 step to update the value in useEffect?
With the useRef
setup, each render re-runs useEffect
but handleSubmit
stays the same. In a normal setup, each render would re-run useCallback
and handleSubmit
would be a new reference to a new function. I can see why on the surface this seems like the same amount of work.
The benefits of the ref approach are what other re-renders happen based on a re-rendering of Form
. Each time the value of text
changes, the parent Form
re-renders and the child input
re-renders since it takes text
as a prop. ExpensiveTree
does not re-render because its prop handleSubmit
maintains the same reference. Of course the name ExpensiveTree
is designed to tell us that we want to minimize re-rendering of that component since it is computationally expensive.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.