The code that occurs with the problem is as follows:
const Parent: = () => { const [val, setVal] = useState(0); const onBtnsClick = () => { (val); }; return ( <div> {val} <button onClick={() => setVal(val => val + 1)}>Add one</button> <Child onClick={onBtnsClick} /> </div> ); }; const Child: <{ onClick: () => void }> = ({ onClick }) => { // useCallback + anti-shake const onBtnClick = useCallback( _.debounce(onClick, 1000, { leading: true, trailing: false }), [] ); return <button onClick={onBtnClick}>Subcomponents</button>; };
reason
Changes in the parent component's status did not cause the child component toonBtnClick
Regenerate, resulting in theval
The value passed in at the beginning0
Solution
Find a way to trigger component refresh to makeonBtnsClick
Printed inval
Always the latest value
Method 1: Remove useCallback, so that every time the parent component triggers a refresh, the child component will be refreshed.
// If the clicked event does not cause the parent component to refresh, thus refreshing the child componentconst onBtnClick = _.debounce(onClick, 1000, { leading: true, trailing: false, });
But this method only applies to one situation: the processing of click events will not cause the parent component to refresh;
If the parent component is refreshed, it will cause the child component to be refreshed, thus debounce is created again, resulting in invalid anti-shake.
If you want the parent component to refresh but the child component does not refresh, you can wrap the parent component function onBtnsClick with useCallback, and the Child component with memo
The complete code is as follows:
const Test: = () => { const [val, setVal] = useState(0); const onBtnsClick = useCallback(() => { (val); setVal(val => val + 2) }, [val]); return ( <div> {val} <button onClick={() => setVal(val => val + 1)}>Add one</button> <div> <Child onClick={onBtnsClick} /> ); }; const Child = memo(({ onClick }) => { const onBtnClick = _.debounce(onClick, 1000, { leading: true, trailing: false, }); return <button onClick={onBtnClick}>Subcomponents</button>; });
Method 2, or refresh the function by listening to val and val value changes
const onBtnClick2 = useCallback( _.debounce(onClick, 1000, { leading: true, trailing: false }), [val] );
Method 3. In the parent component, use val as the key value, and force updates to be triggered every time the val changes.
This change is minimal
<Child key={val} onClick={onBtnsClick} /> // or<div key={val}> <Child onClick={onBtnsClick} /> </div>
This is the article about the solution that the data obtained by calling the parent component method of React child components is not the latest value. For more related React child components calling the parent component to obtain data, please search for my previous article or continue browsing the related articles below. I hope everyone will support me in the future!