React子组件调用父组件方法获取的数据不是最新值的解决方法
作者:一条大河全靠浪
这篇文章主要介绍了React子组件调用父组件方法获取的数据不是最新值的解决方法,文中通过代码示例介绍的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
出现问题的代码如下:
const Parent: React.FC = () => {
const [val, setVal] = useState(0);
const onBtnsClick = () => {
console.log(val);
};
return (
<div>
{val}
<button onClick={() => setVal(val => val + 1)}>加一</button>
<Child onClick={onBtnsClick} />
</div>
);
};
const Child: React.FC<{ onClick: () => void }> = ({ onClick }) => {
// useCallback + 防抖
const onBtnClick = useCallback(
_.debounce(onClick, 1000, { leading: true, trailing: false }),
[]
);
return <button onClick={onBtnClick}>子组件</button>;
};
原因
父组件状态的变更没有引起该子组件中的onBtnClick重新生成,导致方法中的 val 为一开始传入的数值0
解决方法
想办法触发组件刷新,使onBtnsClick 中打印的 val 永远是最新的值
方法一、去掉 useCallback, 这样每次父组件触发刷新,就会刷新子组件
// 如果点击的事件不会导致父组件刷新,从而刷新子组件
const onBtnClick = _.debounce(onClick, 1000, {
leading: true,
trailing: false,
});
但这种方式只适用于一种情况:点击事件的处理不会导致父组件刷新;
如果父组件刷新,就会导致子组件刷新,从而 debounce 又新建,导致防抖无效。
如果想父组件刷新,子组件不刷新,可以父组件函数onBtnsClick用useCallback包裹,Child组件用memo包裹
完整代码如下:
const Test: React.FC = () => {
const [val, setVal] = useState(0);
const onBtnsClick = useCallback(() => {
console.log(val);
setVal(val => val + 2)
}, [val]);
return (
<div>
{val}
<button onClick={() => setVal(val => val + 1)}>加一</button>
<div>
<Child onClick={onBtnsClick} />
);
};
const Child = memo(({ onClick }) => {
const onBtnClick = _.debounce(onClick, 1000, {
leading: true,
trailing: false,
});
return <button onClick={onBtnClick}>子组件</button>;
});
方法二、或者通过监听 val,val 值改变来刷新函数
const onBtnClick2 = useCallback(
_.debounce(onClick, 1000, { leading: true, trailing: false }),
[val]
);
方法三、在父组件中,把 val 作为 key 值,每次 val 变化强制触发更新
这个改动是最小的
<Child key={val} onClick={onBtnsClick} />
// 或者
<div key={val}>
<Child onClick={onBtnsClick} />
</div>
到此这篇关于React子组件调用父组件方法获取的数据不是最新值的解决方法的文章就介绍到这了,更多相关React子组件调用父组件获取数据内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
