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

React.children do not take Functions as Children under consideration #11888

Closed
michal-lipski opened this issue Dec 19, 2017 · 4 comments
Closed

Comments

@michal-lipski
Copy link

My component can have multiple children components. They can be of different types: Strings, JSX Components and functions.

<ChildrenCounter>
  First
  {() => <div>Second</div>}
</ChildrenCounter>

I wanted to render them using React.children.map helper function that unwraps the children opaque data structure. The problem is that children defined as functions seem to be ignored by React.children.map, React.children.count and other helper functions. See the example:

https://jsfiddle.net/bpdsraah/2/

I can access them and render directly from props.children wrapper but it is not a convenient way as one can never know for sure what type it will be.

@gaearon
Copy link
Collaborator

gaearon commented Dec 19, 2017

I think this is intentional, React.Children is intended to work with the children actually renderable by React rather than arbitrary objects (or functions). Can you explain the use case in more detail?

@michal-lipski
Copy link
Author

Fair enough, although it was not clear for me why my child component was not rendered. Maybe there should be some warning from React.Children that this child component was omitted?

In my use case I had function as child component to render table that needed size. And it works fine like it is:

<Widget {...props} >
      {(size) =>(<Table data={prepareData(size)} />)}
 </Widget>

and somewere in Widget render method:

{this.props.children(size)}

Now i wanted to add additional child component to widget:

<Widget {...props} >
      {(size) =>(<Table data={prepareData(size)} />)}
     <Footer {...props}/>
 </Widget>

I need to change render method in Widget to handle its children. And here I wanted to use map to do something like this:

// following doesn't work
{ React.Children.map(this.props.children,(child)=>(_.isFunction(child) ? child(size) : child)) }

That would be most convenient as Widget component can have diferent children depending on uscase.
I was then suprised that it didn't work :)

@gaearon
Copy link
Collaborator

gaearon commented Dec 22, 2017

Why not do this instead?

<Widget {...props} >
  {(size) => (
    <React.Fragment>
      <Table data={prepareData(size)} />)}
      <Footer {...props}/>
    </React.Fragment>
  )}
 </Widget>

Then you don't need to count the children.

@gaearon
Copy link
Collaborator

gaearon commented Jan 6, 2018

I think the above should be a better solution.
If you disagree and would like to change the API behavior I suggest you to file an RFC: https://github.com/reactjs/rfcs
It's not obvious to me how it should behave e.g. for objects if we start making those exceptions, and an RFC would let you expand on that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants