javascriptreactjsobject-composition

Why use this.props.children?


There are other similar questions that have been "answered", but the answers aren't complete and they don't solve the real problem.

This is really a two-parter with a sub-question.

    1. What are the general situations you would want to use this.props.children?

    2. What are some specific situations with examples?

I have read the docs, please don't only quote the docs.

Motivation for this quesiton:

The reason I for this question is that at the time of this question, the docs give a very very general example of how to use it and the methods to use when doing this, but the example don't give us true context. It isn't usable IRL. The example could be literally reused all over an app without rhyme, reason, or regards to sanity. Is that really ok?

I have been told you will use this.props.children, "when you don't know what children will be passed." But technically you never really know what changes may come down the line that require more or different children. So this is pretty ambiguous.

Also I found an interesting article by Jake Trent: http://jaketrent.com/post/send-props-to-children-react/

The article shows how you can add/remove props being passed to these "unknown children" based on the type of the component, which is neat(and possibly a good idea when you build a third party component).

My big takeaway so far is that you are giving power over the children to the parent, when you specify this.props.children Is this a good reason or just a byproduct? (example: proptypes, actual typechecking ... ) but,

   2a. What other things would/could/should you do here?
   2b. What things should you not do?

Examples please!


Solution

  • I like to think of components that make use of props.children as general wrappers, like most other HTML elements.

    Think about the fieldset element.

    <form action="/post">
       <input type="text" name="myValue" placeholder="Some Data" />
       <input type="submit" value="Submit!" />
    </form>
    

    What a pretty form we have made! But I want it to look...different. I want it to kind of look more visually like a form. Like I want some borders around it, maybe a little label in the top to describe it...Ahh I'll wrap it in a fieldset!

    <fieldset>
       <legend>A Pretty Form</legend>
       <form action="/post">
          <input type="text" name="myValue" placeholder="Some Data" />
          <input type="submit" value="Submit!" />
       </form>
    </fieldset>
    

    Now it looks just how I want! Sprinkled in a little legend too, to make this example...legendary.

    The point is though, fieldset provides a reusable component with certain attributes that can be used to group HTML content. It's child elements are absolutely irrelevant to it's functionality.

    Could we use the same principle in React? Yes. And it can be much more powerful!

    Let's say we want to have a special ReactFieldset component, based on an HTML fieldset, that has it's own functionality. I'm not going to code that all out, because who has the time? But imagine you made a ReactFieldset component with a bunch of it's own functionality: it can collapse, it can move, it can do all kinds of things! And it can also hold any kind of content.

    Well, then all you need to do in it's render function is:

    render() {
        return <fieldset { ...superFunctionalityControllingProps }>
        { this.props.children }
        </fieldset>
    }
    

    Tada! You now have a reusable component that has it's own functionality, and can hold any children.

    So the point is: this.props.children can be used when the children aren't really that important at all! The emphasis can actually just be on the component itself, whereas the children are arbitrary components it just happens to house. They needn't even be functionality related at all.

    This is used a lot in React Native. Many different components have their own functionality, but can house any children, because they are just "wrapper" building blocks.