当前位置: 首页 > article >正文

react 子组件调用父组件方法,获取的数据不是最新值

react 子组件调用父组件方法,获取的数据不是最新值

      • 原因
      • 解决方法
          • 方法一、去掉 useCallback, 这样每次父组件触发刷新,就会刷新子组件
          • 方法二、或者通过监听 val,val 值改变来刷新函数
          • 方法三、在父组件中,把 val 作为 key 值,每次 val 变化强制触发更新

出现问题的代码如下:

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 又新建,导致防抖无效。

如果想父组件刷新,子组件不刷新,可以父组件函数onBtnsClickuseCallback包裹,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>

http://www.kler.cn/a/292083.html

相关文章:

  • # ubuntu 安装的pycharm不能输入中文的解决方法
  • 自存 关于RestController请求传参数 前端和后端相关
  • The 3rd Universal CupStage 15: Chengdu, November 2-3, 2024(2024ICPC 成都)
  • SystemVerilog学习——类的继承
  • 【Conda】Windows下conda的安装并在终端运行
  • css:浮动
  • 常用网络协议理解
  • 加锁造成的线程优先级反转
  • 搜维尔科技:使用Facewaer面部捕捉系统制作栩栩如生的脸部动画
  • Maven 的 pom.xml 文件中<dependency> 元素及其各个参数的解释
  • EmguCV学习笔记 C# 10.1 人脸检测 CascadeClassifier类
  • C语言猜数小游戏
  • SpringBoot2:请求处理原理分析-请求Path与接口的映射关系(HandlerMapping)
  • 51单片机——蜂鸣器
  • Springboot +vue 网络零食商城系统
  • 828华为云征文:华为云 Flexus X 实例性能测评——SuperBench 一键窥见性能
  • 数据丢失要怎么处理,助你一键恢复数据
  • 算法笔试-编程练习-好题-02
  • 【操作系统】线程同步之互斥量
  • ssh之登录服务器后,自动进入目录(四十七)
  • ssh登录服务器报错“no matching host key type found. Their offer: ssh-rsa,ssh-dss”解决方法
  • IOS 22 自定义标题栏(Toolbar)
  • 代码随想录 -- 二叉树 -- 翻转二叉树
  • Linux--目录与文件操作函数
  • Leetcode JAVA刷刷站(105)从前序与中序遍历序列构造二叉树
  • SpringBoot 集成 kafka,并消费历史事件