SoFunction
Updated on 2025-04-07

The solution to the data obtained by the React child component calling the parent component method is not the latest value

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 toonBtnClickRegenerate, resulting in theval The value passed in at the beginning0

Solution

Find a way to trigger component refresh to makeonBtnsClickPrinted invalAlways 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!