facebook / react

The library for web and native user interfaces.
https://react.dev
MIT License
229.91k stars 47.07k forks source link

[Question] How to determine parent-child relationship in React Host & Composite components? #9563

Closed FarhadG closed 7 years ago

FarhadG commented 7 years ago

Do you want to request a feature or report a bug? Feature?

What is the current behavior? There doesn't seem anyway to be able to access React's tree.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://jsfiddle.net or similar (template: https://jsfiddle.net/84v837e9/).

What is the expected behavior? Some way to be able to see how elements are nested with their parent-child relationship.

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React? 15+


I'm not sure if this is the right place to inquire about this sort of functionality/feature--if not, I'd appreciate it if you can point me in the right direction--but I have a need to be able to know how child nodes are associated with their parents and to be able to reference them...

For example:

<CustomComponent>
  <h1>Hello, World!</h1>

  <CustomComponent>
    <h1>One</h1>
  </CustomComponent>

  <CustomComponent>
    <h1>Two</h1>

    <CustomComponent>
      <h1>Two One</h1>
    </CustomComponent>

    <CustomComponent>
      <h1>Two Two</h1>
    </CustomComponent>
  </CustomComponent>

</CustomComponent>

As you can see above, there is an inherent tree structure to these components (composite or host) and I'd like to be able to know, at the very minimum, how CustomComponents are nested throughout an entire React application.

I tried a naive solution with the following:

<CustomComponent id="0">
  <h1>Hello, World!</h1>

  <CustomComponent id="0:1">
    <h1>One</h1>
  </CustomComponent>

  <CustomComponent id="0:2">
    <h1>Two</h1>

    <CustomComponent id="0:2:1">
      <h1>Two One</h1>
    </CustomComponent>

    <CustomComponent id="0:2:2">
      <h1>Two Two</h1>
    </CustomComponent>
  </CustomComponent>

</CustomComponent>

Obviously this is not an optimal approach as the user would have to define the entire tree structure with ids and in addition, if the order in which these components mount into the DOM is not linear so it would be hard to reconstruct the tree and be able to perform logic on their relationship to one another.

Any ideas on how to go about this? Thank you for your time and assistance.

gaearon commented 7 years ago

Can you provide more information on why you need this? The React tree is generally considered opaque because opening it up to parent components for introspection and modification can lead to issues that are very hard to debug.

FarhadG commented 7 years ago

Thanks for the quick response, @gaearon. I'm essentially trying to build a scene graph to be able to animate the right sorts of components as needed -- hence needing to know the parent-child relationship.

I tried building that scene graph through the context, however, I ran into a few issues:

I also understand that this may be something suitable for a custom renderer, however, this would be a bit absurd, as I still need all of the functionality behind react-dom but extended with the ability to be able to have access to the tree to build that augmented scene graph.

aweary commented 7 years ago

It's unlikely that we'd implement a way to do parent-child introspection. This is a pretty niche use case, and providing an API for this would break a key invariant for the React tree. I understand that writing a custom renderer seems excessive, but once the renderer API is exposed (https://github.com/facebook/react/pull/10758) it should be a lot easier to do. Thanks!

gaearon commented 7 years ago

There's also super secret coroutine API that might be helpful for "yielding" data from a child back to the parent. It's not exposed publicly yet but there are ways to hack around that if you really want to live on the edge. 😛

FarhadG commented 7 years ago

Gracias, mis amigos.