【问题标题】:Can React.createRef() be created dynamically from an array of state objects?可以从状态对象数组动态创建 React.createRef() 吗?
【发布时间】:2019-07-02 21:28:11
【问题描述】:

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

{
  id: 1,
  group: "header",
  componentType: "headerLogo",
  componentName: "Header 01",
  //...rest of the component properties
}

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

this.headerLogo = React.createRef();
this.headerLogoNavigation = React.createRef();
//...etc.

然后我将引用传递给每个相应的组件,并在我的 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" });
};

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

编辑: 我尝试像这样在构造函数中映射引用:

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

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

【问题讨论】:

  • 是的,您可能应该绑定到 id 或任何唯一知道要滚动到的内容。
  • 我刚刚更新了我的问题。我设法将引用映射到构造函数并将它们绑定到 id,但是在将新组件添加到 usedComponents 数组后,我仍然不知道如何更新它们。您是否知道我该如何实现这一目标?
  • 您将为多少个组件创建参考?如果很多,我可能会避免使用 refs。相反,您可以在每个元素 <div id={component.id} 上应用 id,然后您可以使用 dom 查询获取该元素。 document.getElementById(component.id).scrollIntoView() 或其他。可能不需要 React 来做这个特定的映射/操作
  • 你完全正确。我放弃了 refs 并使用了 document.getElementById,现在一切都像魅力一样。
  • 太棒了!然后我会写一个答案,这样我们就可以结束这个问题了:) 很高兴这有帮助

标签: reactjs


【解决方案1】:

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

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

<div id={component.id}> ... </div>

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

const elemToScrollTo = document.getElementById(component.id)
if (!!elemToScrollTo) {
  elemToScrollTo.scrollIntoView()
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 2016-09-04
    相关资源
    最近更新 更多