我正在尝试为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;组件树中的后代节点的顺序。如果它们是直接的子元素,我猜它会很容易 - 在我的情况下虽然我有嵌套的组件可以输出行。
答案 0 :(得分:0)
我找到了一个狡猾/狡猾的解决方案,通过让儿童组件“注册”&#39;通过在上下文中注入的回调,自己(一个唯一的ID和ref)与容器组件。
容器组件使用功能状态更新累积这些回调,并在需要重新计算的状态下设置标志。
容器的componentDidUpdate
检查重新计算标记,并使用浏览器DOM函数compareDocumentPosition
比较所有DOM注释(通过引用)。下一个状态更新会清除重新计算标记,并包含每个子ID的顺序。
然后通过上下文将此状态传递给所有子节点,他们可以通过ID查找其索引。
显然这很糟糕,但我现在所拥有的一切都很糟糕。仍然希望将赏金奖励给更好的解决方案。
答案 1 :(得分:0)
您似乎依靠render()
在DOM Tree
内为您提供递归结构。它“第一次”工作的原因是所有组件需要在第一次呈现给react
时进行渲染。
但是,对render()
的后续ColumnContainer
次调用并不意味着对子组件进行渲染,因为他们的state
或props
可能没有更改。
我认为你应该尝试以下方法:
ColumnContainer.Row
注册更改为ColumnContainer
数组,方式是第一次通话时rowIdx
中的孩子 rembember state
然后将此值重用于后续render
次调用。(所以要有效地做到这一点,你需要:)
在两个函数调用中更改注册过程(这两个函数应该在您的上下文中):
rowIdx
并记住它的函数。 (仅当您没有rowIdx
的缓存值时才会调用此函数)rowIdx
作为参数的第二个函数。 (这个函数就像现在一样,每次调用。)