React:在层次结构中获取组件顺序

时间:2018-06-09 17:41:02

标签: javascript reactjs

我正在尝试为CSS网格实现帮助程序组件。我喜欢(准备好自己):

<ColumnContainer columns={[ "1em", "1fr", "auto", "auto", "1em", "auto"]}>
  <ColumnContainer.Row>
    { rowIdx => (
      <div style={{ gridRow: rowIdx, gridColumn: "1 / 3" }}>
      </div>
    )}
  </ColumnContainer.Row>
</ColumnContainer>

ColumnContainer

  • 容器div是否设置了display: grid并设置了各种网格属性
  • 也是一个上下文提供者

然后,ColumnContainer.Row

  • 基本上是上下文消费者
  • 扮演孩子的角色
  • 不需要成为ColumnContainer的直接孩子 - 因此使用上下文

提供的上下文是一个整数layoutVersion,每当要更改的行集(触发重新渲染)时都会递增,并且 - hacks of hacks - 一个空数组。

这个想法是,当每个ColumnContainer.Row呈现时,它将自身(可以是任何对象)添加到其上下文中传递引用的数组,并将子函数与数组的大小一起呈现为参数(行索引)。

信不信由你,这适用于第一次渲染,如果只是将行添加到最后。

然而,当组件被添加到&#34;中&#34;在组件DOM中,生成的渲染行是无序的(但不重叠)。我认为,在新布局版本(重新渲染)的情况下,所有ColumnContainer.Row都被重新渲染,但不一定在“自然”中。他们在,即在DOM中。

我的猜测是,根据以某个顺序调用render()的组件是个坏主意,以及在render()中修改上下文属性的内容。

我的其他选择是什么 - 我真正想要的是了解自然&#39;组件树中的后代节点的顺序。如果它们是直接的子元素,我猜它会很容易 - 在我的情况下虽然我有嵌套的组件可以输出行。

2 个答案:

答案 0 :(得分:0)

我找到了一个狡猾/狡猾的解决方案,通过让儿童组件“注册”&#39;通过在上下文中注入的回调,自己(一个唯一的ID和ref)与容器组件。

容器组件使用功能状态更新累积这些回调,并在需要重新计算的状态下设置标志。

容器的componentDidUpdate检查重新计算标记,并使用浏览器DOM函数compareDocumentPosition比较所有DOM注释(通过引用)。下一个状态更新会清除重新计算标记,并包含每个子ID的顺序。

然后通过上下文将此状态传递给所有子节点,他们可以通过ID查找其索引。

显然这很糟糕,但我现在所拥有的一切都很糟糕。仍然希望将赏金奖励给更好的解决方案。

答案 1 :(得分:0)

您似乎依靠render()DOM Tree内为您提供递归结构。它“第一次”工作的原因是所有组件需要在第一次呈现给react时进行渲染。

但是,对render()的后续ColumnContainer次调用并不意味着对子组件进行渲染,因为他们的stateprops可能没有更改。

我认为你应该尝试以下方法:

  1. 将您的ColumnContainer.Row注册更改为ColumnContainer数组,方式是第一次通话时rowIdx中的孩子 rembember state然后将此值重用于后续render次调用。
  2. (所以要有效地做到这一点,你需要:)

    1. 在两个函数调用中更改注册过程(这两个函数应该在您的上下文中):

      • 为孩子获取rowIdx并记住它的函数。 (仅当您没有rowIdx的缓存值时才会调用此函数)
      • 执行工作但不需要rowIdx作为参数的第二个函数。 (这个函数就像现在一样,每次调用。)