I'm trying to implement helper components for CSS Grids. I have something like (prepare yourself):

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

ColumnContainer :

Is a container div with display: grid and various grid properties set up

with and various grid properties set up Is also a context provider

Then, ColumnContainer.Row :

Is basically a context consumer

Takes a function as a child

Doesn't need to be a direct child of ColumnContainer - hence using context

The context provided is an integer, layoutVersion , which is incremented whenever the set of rows is intended to change (to trigger a re-render), and - hack of hacks - an empty array.

The idea is, as each ColumnContainer.Row renders, it adds itself (could be any object) to the array whose reference is passed in the context, and renders the child function with the size of the array as the parameter (row index).

Believe it or not, this works, for the first render and if rows are just added to the end.

However, when components are added in the "middle" of the component DOM, the resulting rendered rows are out-of-order (but not overlapping). Meaning, I think, that in the case of a new layout version (re-render), all the ColumnContainer.Row s are re-rendered, but not necessarily in the 'natural' order they are in, i.e. in the DOM.

My guess is that depending on components to have render() called in a certain order is a bad idea, as well as modifying the contents of context properties in render() .

What are my other options - what I really want is to know the 'natural' order of descendent nodes within a component tree. If they were direct child elements, I'd guess it would be easy - in my case though I have nested components which can output rows.