可以从状态对象数组动态创建 React.createRef() 吗?

Gor*_*sic 4 reactjs

我有一个固定在侧边栏内的样式单选按钮列表,单击时,将相应的组件从主区域滚动到视图中。单选按钮列表和主区域内的组件都从称为 usedComponents 的状态数组映射,该数组包含组件属性和 id 的对象。假设数组包含 10 个对象,每个对象如下所示:

{
  id: 1,
  group: "header",
  componentType: "headerLogo",
  componentName: "Header 01",
  //...rest of the component properties
}
Run Code Online (Sandbox Code Playgroud)

为了在单选按钮单击时滚动到视图中,我必须在构造函数中创建对组件的引用。我手动为 usedComponents 状态数组中包含的每个组件创建了引用,并将它们绑定到 componentType,如下所示:

this.headerLogo = React.createRef();
this.headerLogoNavigation = React.createRef();
//...etc.
Run Code Online (Sandbox Code Playgroud)

然后我将引用传递给每个相应的组件,并在我的 selectComponentHandler 中设置 scrollIntoView 以调用与主区域组件引用相对应的单选按钮 ID。selectComponentHandler 看起来像这样:

selectComponentHandler = e => {
  const value = Number(e.target.value);
  const id = e.target.id; //returns componentType. For example "headerLogo"
  this.setState(prevState => {
    let selected = prevState.usedComponents
      .filter(item => item.id === value)
      .shift();
    let unSelected = prevState.usedComponents
      .filter(item => item.selected === true)
      .shift();
    if (unSelected) {
      unSelected.selected = false;
    }
    selected.selected = true;
    return { unSelected, selected };
  });
  this[id].current.scrollIntoView({ block: "start", behavior: "smooth" });
};
Run Code Online (Sandbox Code Playgroud)

但是,我使用 react-beautiful-dnd 以便能够通过将新组件拖动到主区域来添加新组件,并且每当我添加已包含在 usedComponents 数组中的类型的新组件时,它都有与相同类型的旧组件相同的参考。这使得 scrollIntoView 始终滚动到排在第一位的相同类型的组件,无论我选择哪一个。有没有办法为 usedComponents 数组中的所有组件动态创建引用,通过映射它们,并在插入新组件时更新它们。也许将它们与 ID 联系起来?

编辑:我尝试在构造函数中映射引用,如下所示:

this.state.usedComponents.map(component => {
  const id = component.id.toString();
  return (this[id] = React.createRef());
});
Run Code Online (Sandbox Code Playgroud)

它适用于已在 used Components 数组中的组件,但是当通过拖放将新对象插入 usedComponents 数组时,我仍然不知道如何更新引用。新插入的组件基本上没有引用。

Joh*_*ell 5

就像我在评论中提到的那样,我不会走动态参考的路线。这些 refs 的范围/大小可能会变大,并且有更好的方法来处理这个问题。只需使用 DOM。

渲染时,您可以将组件 ID 放在要滚动到的 html 元素上

<div id={component.id}> ... </div>
Run Code Online (Sandbox Code Playgroud)

然后当您想滚动到该元素时,只需查询该元素的 DOM 并滚动到它

const elemToScrollTo = document.getElementById(component.id)
if (!!elemToScrollTo) {
  elemToScrollTo.scrollIntoView()
}
Run Code Online (Sandbox Code Playgroud)