【问题标题】:Conditionally assign ref in react在反应中有条件地分配 ref
【发布时间】:2021-05-26 05:05:57
【问题描述】:

我正在做一些反应,遇到了一个我自己无法解决的挑战。我在这里和其他地方搜索过,我找到了标题相似的主题,但与我遇到的问题没有任何关系,所以我们开始吧:

所以我有一个数组,它将被映射到 React、组件中,通常是这样的:

export default ParentComponent = () => {

//bunch of stuff here and there is an array called arr

return (<>
 
    {arr.map((item, id) => {<ChildComponent props={item} key={id}>})}

</>)

}

但问题是,父元素中有一个状态,它存储当前选择的其中一个 ChildComponents 的 id(我通过设置上下文并在 ChildComponent 中设置此状态来做到这一点),然后问题是我必须引用当前选择的 ChildComponent 内部的一个节点。我可以转发 ref 没问题,但我也想只在当前选择的 ChildComponent 上分配 ref,我想这样做:

export default ParentComponent = () => {

//bunch of stuff here and there is an array called arr and there's a state which holds the id of a  selected ChildComponent called selectedObjectId

const selectedRef = createRef();

return (<>
    <someContextProvider>
    {arr.map((item, id) => {
       <ChildComponent 
        props={item} 
        key={id} 
        ref={selectedObjectId == id ? selectedRef : null}
       >
    })}
   <someContextProvider />
</>)

}

但我已经尝试过了,但我们做不到。那么,如果某个条件为真,如何动态地将 ref 分配给数组的一个特定元素呢?

【问题讨论】:

  • 使用 React ref 来存储相当于活动 id 的内容似乎是对 React ref 的不好使用,特别是考虑到您已经在使用 React 上下文......为什么不只访问每个孩子的上下文并将活动 id 与子组件的 id 匹配?
  • 实际上我正在使用来自@react-three/fiber 和后处理的SelectiveBloom 效果,为了实现这一点,SelectiveBloom 需要一个网格参考,它会应用bloom。所以我需要对于每个 ChildComponent,如果选定的组件 id 是这个 ChildComponent 的 id,我想将其中的网格的 ref 传递给父组件中的 SelectiveBloom 效果。换句话说,我只想在所选对象中应用 SelectiveBloom。

标签: reactjs react-hooks react-ref


【解决方案1】:

不能动态分配ref,但是可以全部存储,通过id访问

export default ParentComponent = () => {

//bunch of stuff here and there is an array called arr and theres a state wich holds the id of a  selected ChildComponent called selectedObjectId


let refs = {}

// example of accessing current selected ref
const handleClick = () => {
    if (refs[selectedObjectId])
        refs[selectedObjectId].current.click() // call some method
}

return (<>
    <someContextProvider>
    {arr.map((item, id) => {
       <ChildComponent 
        props={item} 
        key={id} 
        ref={refs[id]}
       >
    })}
   <someContextProvider />
</>)

}

【讨论】:

  • 谢谢,但这对性能不是很不利吗? React 文档明确表示不要滥用 refs,而且我不会使用其中任何一个。
  • Medet 和 Daniel:请参阅 this answer 以生成 React 参考。请注意,父组件还使用单个 ref 来保存子组件的 ref 数组。事实上,Medet,您的问题几乎与我回答的另一个问题重复,即它具有相同的问题/陷阱。
  • 嗨 Drew,我已经看到了那个解决方案,但我认为即使我只使用一个(将在对象之间迁移)创建一个 refs 数组也是非常糟糕的性能。我错了吗?好吧,我想这是唯一的解决方案。谢谢!
  • @DanielGuedes Refs 应该为每个组件创建一次,并通过重新渲染保持...在任何性能成本。换句话说,我认为您甚至不会注意到除了可能更多的内存使用之外的任何东西。
  • 非常感谢,还在学习中,很高兴有你这样的人!
【解决方案2】:

您可以使用 props 扩展运算符 {...props} 通过首先构建 props 对象来传递条件 ref。例如

export default ParentComponent = () => {
  const selectedRef = useRef(null);

  return (
    <SomeContextProvider>
      {arr.map((item, id) => {
        const itemProps = selectedObjectId == id ? { ref: selectedRef } : {};
        return ( 
          <ChildComponent 
            props={item} 
            key={id} 
            {...itemProps}
          />
        );
      })}
    <SomeContextProvider />
  )
}

【讨论】:

    【解决方案3】:

    解决方案

    就像 Drew 在 Medets answer 中评论的那样,唯一的解决方案是创建一个 ref 数组并通过简单地将 ChildElement 的索引与 ref 数组的索引匹配来访问所需的数组,正如我们可以看到的 here。我们发现实际上无法在对象之间移动 ref,但这样做的性能成本应该不相关。

    【讨论】:

      猜你喜欢
      • 2021-04-18
      • 2011-05-18
      • 2019-08-05
      • 2021-02-19
      • 2019-03-20
      • 2017-01-04
      • 1970-01-01
      • 1970-01-01
      • 2022-01-05
      相关资源
      最近更新 更多