React Nesting Components


Example

A lot of the power of ReactJS is its ability to allow nesting of components. Take the following two components:

var React = require('react');
var createReactClass = require('create-react-class');

var CommentList = reactCreateClass({
  render: function() {
    return (
      <div className="commentList">
        Hello, world! I am a CommentList.
      </div>
    );
  }
});

var CommentForm = reactCreateClass({
  render: function() {
    return (
      <div className="commentForm">
        Hello, world! I am a CommentForm.
      </div>
    );
  }
});

You can nest and refer to those components in the definition of a different component:

var React = require('react');
var createReactClass = require('create-react-class');

var CommentBox = reactCreateClass({
  render: function() {
    return (
      <div className="commentBox">
        <h1>Comments</h1>
        <CommentList /> // Which was defined above and can be reused
        <CommentForm /> // Same here
      </div>
    );
  }
});

Further nesting can be done in three ways, which all have their own places to be used.

1. Nesting without using children

(continued from above)

var CommentList = reactCreateClass({
  render: function() {
    return (
      <div className="commentList">
        <ListTitle/>
        Hello, world! I am a CommentList.
      </div>
    );
  }
});

This is the style where A composes B and B composes C.

Pros

  • Easy and fast to separate UI elements
  • Easy to inject props down to children based on the parent component's state

Cons

  • Less visibility into the composition architecture
  • Less reusability

Good if

  • B and C are just presentational components
  • B should be responsible for C's lifecycle

2. Nesting using children

(continued from above)

var CommentBox = reactCreateClass({
  render: function() {
    return (
      <div className="commentBox">
        <h1>Comments</h1>
        <CommentList>
            <ListTitle/> // child
        </CommentList>
        <CommentForm />
      </div>
    );
  }
});

This is the style where A composes B and A tells B to compose C. More power to parent components.

Pros

  • Better components lifecycle management
  • Better visibility into the composition architecture
  • Better reusuability

Cons

  • Injecting props can become a little expensive
  • Less flexibility and power in child components

Good if

  • B should accept to compose something different than C in the future or somewhere else
  • A should control the lifecycle of C

B would render C using this.props.children, and there isn't a structured way for B to know what those children are for. So, B may enrich the child components by giving additional props down, but if B needs to know exactly what they are, #3 might be a better option.

3. Nesting using props

(continued from above)

var CommentBox = reactCreateClass({
  render: function() {
    return (
      <div className="commentBox">
        <h1>Comments</h1>
        <CommentList title={ListTitle}/> //prop
        <CommentForm />
      </div>
    );
  }
});

This is the style where A composes B and B provides an option for A to pass something to compose for a specific purpose. More structured composition.

Pros

  • Composition as a feature
  • Easy validation
  • Better composaiblility

Cons

  • Injecting props can become a little expensive
  • Less flexibility and power in child components

Good if

  • B has specific features defined to compose something
  • B should only know how to render not what to render

#3 is usually a must for making a public library of components but also a good practice in general to make composable components and clearly define the composition features. #1 is the easiest and fastest to make something that works, but #2 and #3 should provide certain benefits in various use cases.