Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compound components parent initialization. #15320

Closed
pumanitro opened this issue Apr 4, 2019 · 2 comments
Closed

Compound components parent initialization. #15320

pumanitro opened this issue Apr 4, 2019 · 2 comments
Labels
Resolution: Stale Automatically closed due to inactivity

Comments

@pumanitro
Copy link

pumanitro commented Apr 4, 2019

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

Problem
There is no easy way of initializing Parent (not exactly direct) by its children (not exactly direct).

Example
I would like to create Compound Component like;

<Parent>
  <Parent.Child value="child1" label="label1" />
  <Parent.Child value="child2" label="label2" />
</Parent>

and spread information through <Parent.Child /> component directly to specified <Parent /> before they rendering.

Why I need this
With such pattern I can:

  • edit styles of elements of the given compound component easily e.g. <Parent.Child className={...} />
  • add custom children to the given parent of the compound components or wrap its children - they don't need to be direct children of the parent component. E.g.
<Parent>
  <StyledWrapper>
    <Parent.Child value="child1" label="label1" />
  </StyledWrapper>
  <Parent.Child value="child2" label="label2" />
  <SomeExampleIcon />
</Parent>

3 solutions I've tried

  1. Context Api
    I can initialize <Parent/> component with Context API usage by its children but:
  • they need to be rendered first, so I can't get information about them in the <Parent /> component at the first render.
  • unwanted, one, additional whole compound component rerender (caused by context change) - "blink effect"
    E.g.
    I would like to display in <Parent /> component amount of its children (not exactly direct).
    Firstly Parent display nothing because its children have not been rendered yet. Then I initialize Parent by using context API, Parent rerenders, correct value is displayed by Parent (initialization effect visible, by small blink)
  1. Mutation
    Yes, I wanted to use mutation to prevent blink effect and unnecessary component rerender, but:
  • it will work only for callbacks usage, not If Parent needs to know about its children before their rendering.
    E.g.
    Parent renders with context API, children renders -> mutates context object, Parent doesn't rerender and can access the actual value in some callback, but not before children render.
  1. Deep Children Traverse
    I wrote something like this:
export const deeplyTraverseChildren = (children, callback) => {
  React.Children.forEach(children, child => {
    callback(child);
    if (child.props.children) {
      deeplyTraverseChildren(child.props.children, callback);
    }
  });
};

It let me use callback to play with deeply traversed children of given Parent component.
With that, I can Initialize some information about their children before they will be rendered.
Then I can spread data as I want, but:

  • there can be a situation where Children component ends up with not used properties by its own, but they are used only by it parent (not exactly direct)

Maybe you have some better ideas? If yes, please share them.

I know it breaks in some cases of UP -> Down data flow, but who said its a golden rule for everything. Look for pros that we can achieve with this functionality.

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

@stale
Copy link

stale bot commented Jan 10, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution.

@stale stale bot added the Resolution: Stale Automatically closed due to inactivity label Jan 10, 2020
@stale
Copy link

stale bot commented Jan 17, 2020

Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please create a new issue with up-to-date information. Thank you!

@stale stale bot closed this as completed Jan 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Stale Automatically closed due to inactivity
Projects
None yet
Development

No branches or pull requests

1 participant