Register to get access to free programming courses with interactive exercises

Children JS: React

UI elements have a hierarchical structure. For example, the card in Bootstrap:

<div class="card">
  <img class="card-img-top" src="..." alt="Card image cap">
  <div class="card-body">
    <h4 class="card-title">Card title</h4>
    <p class="card-text">
      Some quick example text to build on the card title and make up the bulk of the card's content.
    </p>
    <a href="#" class="btn btn-primary">Go somewhere</a>
  </div>
</div>

Card block may contain a picture and a body inside. The body, in turn, can consist of a header and text, and the text can be anything. The same applies both to the simplest elements of HTML itself, such as the <div> tag, and to the rest of Bootstrap's components, such as modal windows and navigation.

HTML conforms to the nature of UI and naturally allows you to create compositions of elements by nesting tags within each other. JSX works the same way. So far, this feature has only been used in the course for embedded components. Now it's time to learn how to repeat this behavior in self-written components. The example is based on the <Alert /> component from Bootstrap.

See the Pen YxgWVm by Hexlet (@hexlet) on CodePen.

In the example above, only the main div is mandatory. The content depends on the specific situation. It's substituted using the children property.

See the Pen js_react_children_alert_component by Hexlet (@hexlet) on CodePen.

Note that the component has come to be used as a paired tag in JSX:

const vdom = (
  <Alert>
    <p>Whenever you need to, be sure to use margin utilities to keep things nice and tidy.</p>
  </Alert>
);

Everything between the opening and closing tags goes inside the children prop.

But beware: the children property's data type depends on the content. In the simplest case, when the tag is used as a single <div />, this property will be undefined.

If this content is a string, it'll be inside children. After some processing, anyway. JSX removes whitespace from the beginning and end of a string, including blank lines. The following examples will be displayed in the same way:

<div>Hello World</div>

<div>
  Hello World
</div>

<div>
  Hello
  World
</div>

<div>

  Hello World
</div>

Any single child component will also be represented by itself in children. In all other cases, children will contain an array.

If you look closely at the React documentation, you'll see the following definition of children: "children are an opaque data structure". In other words, you can't unequivocally rely on the type of this prop, since anything can be conveyed on the outside.

This kind of behavior can lead to hard-to-find mistakes. For example, checking this.props.children.length doesn't always give the number of children. If children children is a single element, such as a string, then the length property will return the length of that string.

class MyComponent extends React.Component {
  render() {
    const { children } = this.props
    return <p>Count: {children.length}</p>
  }
}

// <p>Count: 4</p>
<MyComponent>Text</MyComponent>

That's why React provides a set of functions designed to manipulate the children prop. They're all available in React.Children. These functions are aware of the features of children, they check the type themselves and make the necessary checks depending on the type of data.

React.Children.map()

You may remember from the lesson on processing collections that when you work with a list, each item needs to be assigned a key prop. If you don't do this with React.Children.map, React won't throw a warning. This is done intentionally, because descendants usually don't have unique identifiers.

React.Children.count()

class ChildrenCounter extends React.Component {
  render() {
    const { children } = this.props
    return <p>Count: {React.Children.count(children)}</p>
  }
}

// Count: 1
<ChildrenCounter>
  Second!
</ChildrenCounter>

// Count: 2
<ChildrenCounter>
  <p>First</p>
  <ChildComponent />
</ChildrenCounter>

// Count: 2
<ChildrenCounter>
  {() => <h1>First!</h1>} // will be skipped because it's not a dom-element
  Second!
  <p>Third!</p>
</ChildrenCounter>

In addition to the above, you may need to handle child elements before output by changing a part in their props. Of course, this can't be done directly, because props are immutable. You can achieve this behavior by cloning elements with React.cloneElement().


Hexlet Experts

Are there any more questions? Ask them in the Discussion section.

The Hexlet support team or other students will answer you.

About Hexlet learning process

For full access to the course you need a professional subscription.

A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.

Get access
130
courses
1000
exercises
2000+
hours of theory
3200
tests

Sign up

Programming courses for beginners and experienced developers. Start training for free

  • 130 courses, 2000+ hours of theory
  • 1000 practical tasks in a browser
  • 360 000 students
By sending this form, you agree to our Personal Policy and Service Conditions

Our graduates work in companies:

<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.bookmate">Bookmate</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.healthsamurai">Healthsamurai</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.dualboot">Dualboot</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.abbyy">Abbyy</span>
Suggested learning programs

From a novice to a developer. Get a job or your money back!

Frontend Developer icon
Profession
beginner
Development of front-end components for web applications
start anytime 10 months

Use Hexlet to the fullest extent!

  • Ask questions about the lesson
  • Test your knowledge in quizzes
  • Practice in your browser
  • Track your progress

Sign up or sign in

By sending this form, you agree to our Personal Policy and Service Conditions
Toto Image

Ask questions if you want to discuss a theory or an exercise. Hexlet Support Team and experienced community members can help find answers and solve a problem.