我可以在循环内使用 useEffect 确保其尺寸恒定吗?

2024-01-09

我有一个功能性的 React 组件(更多的是非 React 对象的代理),如下所示:

function ProxyComponent({onEvent1, onEvent2, onEvent3 ...}){
  useEffect(()=>{
    someObject?.on('event1', onEvent2);
    return someObject?.off('event1', onEvent2);
  },[onEvent2, someObject])

  useEffect(()=>{
    someObject?.on('event1', onEvent1);
    return someObject?.off('event1', onEvent1);
  },[onEvent1, someObject])
  .
  .
  .
}

除了有很多事件,而且这里有一个明显的模式。所以我想这样做:

function ProxyComponent(props){
  const events = {
    'event1': props.onEvent1 ?? null,
    ...
    'event20': props.onEvent20 ?? null
  }
  

  for (const [name, handler] of Object.entries(events)) {
    useEffect(()=>{
      handler && someObject?.on(name, handler);
      return handler && someObject?.off(name, handler);
    },[handler, someObject])
  }

}

The 钩子规则 https://reactjs.org/docs/hooks-rules.html明确表示不支持这种用法,但我想知道我如何能够自动化这个模式,同时仍然在钩子规则之内【这是主要问题】

Notes:

  1. The .on and .off方法会创建网络请求,因此最好尽可能少地调用它们。

  2. 将循环移至 useEffect 内部会产生两个复杂情况:

    A。一个非常长的依赖数组 [onEvent1, ..., onEvent20]。我非常怀疑[...Object.values(events)] works.

    b.单个处理程序中的每次更改都会导致多个.offs 并用 new 撤消它.on又来了。除了效率低下之外,在我的具体情况下,我想避免这种情况,因为注释#1。


我怀疑打电话useEffect如果迭代次数绝对静态,则在循环内是可以的。以下不会引发错误:

const App = () => {
    for (let i = 0; i < 3; i++) {
      React.useEffect(() => {
        console.log('an effect');
      }, []);
    }
    return 'foo';
};

ReactDOM.createRoot(document.querySelector('.react')).render(<App />)
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div class='react'></div>

规则的要点是:

通过遵循此规则,您可以确保每次渲染组件时都以相同的顺序调用 Hook。这就是允许 React 在多个 useState 和 useEffect 调用之间正确保留 Hooks 状态的原因。

静态循环可以满足这一点。循环often有条件会导致它们执行不同的次数,这可能就是为什么“不要在循环内使用钩子”的原因 - 但总括语句并不像 React 实际要求的那么精确。

所以,和你的

for (const [name, handler] of Object.entries(events)) {
    useEffect(()=>{

可能没问题——唯一的问题是短绒。

设置替代方法是可能的,只是有点复杂。你需要模仿的行为useEffect通过将某物的当前值与先前值进行比较,而不在循环中使用钩子。一种选择是将处理程序(通过 props 传递)置于状态中。每次渲染时,都会检查道具并检查是否与状态存在任何不平等。如果有,请重新订阅。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我可以在循环内使用 useEffect 确保其尺寸恒定吗? 的相关文章

随机推荐

  • 三星手机和Notification.FLAG_INSISTENT错误?

    我开发了一个计时器应用程序 但有些人注意到三星 Galaxy 或 Spica 上的通知永远不会停止 我的通知中附加了这些标志 notification flags Notification FLAG AUTO CANCEL Notifica
  • 对象实体到 CSV 序列化/转换

    如何在 C 中将所有值 属性 写入 csv 格式的字符串 例如 class Person string firstName string lastName int age Person person new Person Kevin Kli
  • PyOpenCL 中的时间测量

    我正在 FPGA 和 GPU 中使用 PyOpenCL 运行内核 为了测量执行所需的时间 我使用 t1 time event mykernel queue c width c height block size block size d c
  • “make clean”导致“没有规则使目标‘clean’”

    我运行的是 Ubuntu 10 04 每当我跑步时make clean 我明白了 make 没有规则可以使目标 干净 停止 这是我的生成文件 CC gcc CFLAGS g pedantic O0 std gnu99 m32 Wall PR
  • 如何实现 getSupportParentActivityIntent() 来动态设置 android 中向上按钮的活动[重复]

    这个问题在这里已经有答案了 Android中如何知道哪个父Activity调用了子Activity 假设我有三个活动 A B 和 C A 和 B 是父活动 C 是子活动 这意味着 C 可以从 A 或 B 启动 那么我如何知道哪个父活动导致启
  • 通过配对蓝牙打印机 Canon CP 900、CP 800 打印图像

    我需要将我的应用程序与配对的蓝牙设备连接 这将打印图像 via 蓝牙打印机 佳能 CP900 和 CP800 SELPHY And I 没有找到 any 佳能打印机 Android SDK任何帮助或链接都将是有意义的 我找到了这个link
  • 通过映射另一个 Observable 返回一个 Observable

    我正在尝试映射一个可观察值 从返回的可观察值中获取一个值 然后将该值输入到另一个可观察值中并返回该结果 这是我到目前为止所拥有的 getJobsByUser user User Observable
  • 将子类传递给方法但将超类作为参数?

    我有一个抽象类Vehicle有 2 个已实现的子类RedVehicle and YellowVehicle 在另一堂课上我有一个List
  • Mongodb:从 mongo shell 中的 ObjectId 执行日期范围查询

    我有一个看起来像这样的集合 id ObjectId 50a68673476427844b000001 other fields 我想做一个范围查询来查找两个日期之间的记录 我知道我可以通过执行以下操作从 mongo shell var 中的
  • 将 div 从父网站复制到 iframe 中的文本区域

    在谷歌翻译中 我制作了谷歌翻译的第二个实例 var makediv document createElement secondinstance makediv innerHTML makediv setAttribute id iframe
  • Serilog 缺少什么命名空间?

    I am able to use LoggerConfiguration in my C code with various Serilog Sinks but my compiler is complaining about the sp
  • PHP 中如何判断一个日期是否在两个日期之间?

    我需要知道是否 paymentDate 2010 年 12 月 31 日 有效期为 contractDateBegin 01 01 2001 和 contractDateEnd 01 01 2012 日 月 年格式 从 PHP 5 3 开始
  • Python HTMLParser:UnicodeDecodeError

    我正在使用 HTMLParser 来解析我用 urllib 下拉的页面 并且遇到了UnicodeDecodeError将某些传递给时的异常HTMLParser 我尝试使用chardet检测编码并转换为ascii or utf 8 the d
  • 改变div的背景颜色

    这很简单 我搜索过但找不到确切的答案 我想做的就是有一个 div 当你点击链接时它会改变颜色 我想要大约 3 或 4 种颜色选择 我该怎么做 Thanks 这是一个快速解决方案
  • 使用 SignalR 的 WCF 服务

    我有一个网络应用程序 仪表板上几乎没有图表 图表数据是在客户端调用 WCF 服务方法的 document ready 函数中获取的 我现在想要的是在我的应用程序中使用 SignalR 我对 SignalR 真的很陌生 我如何从 Signal
  • 如何进行内核线程通信?

    如何让内核模块中的线程进行通信 我正在编写一个内核模块 我的架构将使用三个需要通信的线程 到目前为止 我的研究使我相信唯一的方法是使用共享内存 声明全局变量 和锁定机制来同步线程之间的读 写 那里关于这方面的材料相当稀缺 我还有其他可以考虑
  • 当您的应用程序安装在 Android 上时,您可以运行 Intent 或脚本吗?

    例如 RPM 有 post postun pre preun 允许您编写在安装过程的不同阶段运行的脚本 我想做一些事情 比如在安装我的 Android 应用程序时创建和填充数据库 Ted 不 抱歉 这是明确不支持的
  • 将生成的进程的输出捕获到字符串

    背景 我正在开发一个程序 需要能够捕获stdout stderr以及程序的返回值 理想情况下 我希望将这些捕获到存储在对象内的字符串中 该对象保存过程的详细信息 我目前有一些代码 可以使用一些 在我看来 古老的 C 文件处理魔法将输出保存到
  • 向 AVM2 添加语言

    我对创建一种在 AVM2 上运行的语言很感兴趣 并且正在寻求从哪里开始的建议 我确实意识到这绝不是一项微不足道的任务 但我想尝试一下 至少在此过程中了解更多有关实现语言的知识 我一直在研究 ANTLR 并一直在阅读语言开发的语法问题 我正在
  • 我可以在循环内使用 useEffect 确保其尺寸恒定吗?

    我有一个功能性的 React 组件 更多的是非 React 对象的代理 如下所示 function ProxyComponent onEvent1 onEvent2 onEvent3 useEffect gt someObject on e