在 React 中使用基于循环的参数有效地定义 useCallback 函数
P粉550823577
P粉550823577 2024-01-16 14:06:30
[React讨论组]

问题

在反应中,我确实经常需要使用诸如 useCallback 之类的内容来记忆项目列表中的函数(通过循环创建),以避免由于引用标识符不匹配而导致单个元素发生更改而重新渲染所有组件……不幸的是,这是令人惊讶的是很难到期。例如,考虑以下代码:

const MyComp = memo({elements} => {
  {
    elements.map((elt, i) => {
      <>{elt.text}

其中 Button 是由 ant design 等提供的外部组件。然后,这个函数引用在每次渲染时都会不同,因为它是内联的,因此强制重新渲染。

一个(糟糕的)解决方案

为了避免这个问题,我可以想到另一种解决方案:创建一个新组件 MyButton,它接受两个属性 index={i}onClick 而不是单个 onClick,并将参数 index 附加到任何调用onClick:

const MyButton = ({myOnClick, id, ...props}) => {
  const myOnClickUnwrap = useCallback(e => myOnClick(e, id), [myOnClick]);
  return 

为什么我想要更好的方法

虽然这确实有效,但由于多种原因,这是非常不实用的:

  • 代码混乱
  • 我需要包装 Button 等外部库中的所有元素,并重写原本不打算处理这种嵌套的组件……这会破坏模块化并使代码更加复杂
  • 这种组合很糟糕:如果我想将元素嵌套在多个列表中,它会更脏,因为我需要在列表的每一级添加一个新索引,例如 ,这意味着我需要完全通用地创建一个更复杂的版本 MyButton 来检查嵌套级别的数量。我无法使用 index={[index1,index2,index3]},因为这是一个数组,因此没有稳定的引用。
  • 据我所知,indexes 的命名没有约定,这意味着项目之间共享代码或开发库更加困难

我缺少更好的解决方案吗?考虑到列表无处不在,我不敢相信对此没有适当的解决方案,而且我很惊讶地看到这方面的文档很少。

编辑 我尝试这样做:

// Define once:
export const WrapperOnChange = memo(({onChange, index, Component, ...props}) => {
    const onChangeWrapped = useCallback(e => onChange(e, index), [onChange, index]);
    return 
});

export const WrapperOnClick = memo(({onClick, index, Component, ...props}) => {
    const onClickWrapped = useCallback(e => onClick(e, index), [onClick, index]);
    return 
});

并像这样使用它:

const myactionIndexed = useCallback((e, i) => dispatch(removeSolverConstraint({id: i})), []);
return 
但这仍然不完美,特别是我需要一个用于不同嵌套级别的包装器,每当我定位一个新属性时我都需要创建一个新版本(onClickonChange,...),如果我有它就无法直接工作多个属性(例如 onClickonChange),我以前从未见过这个,所以我想有更好的解决方案。

编辑 我尝试了各种想法,包括使用 fast-memoize,但我仍然不明白所有结果:有时,fast-memoize 有效,有时失败......而且我不知道 fast-memoize 是否是推荐的解决方案:似乎对于如此常见的用例使用第三方工具很奇怪。在这里查看我的测试https://codesandbox.io/embed/magical-dawn-67mgxp?fontsize=14&hidenavigation=1&theme=dark

P粉550823577
P粉550823577

全部回复(0)
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号