GithubHelp home page GithubHelp logo

react-this-props-children-ios-0916's Introduction

React this.props.children

Overview

We'll cover what this.props.children means in the context of a React component.

Objectives

  1. Use this.props.children to render content in our component
  2. Explain how to use the React.Children utilities
  3. Use and iterate over child components

Children in a component

Sideshow Bob

In React, a component can have one, many or no children. Consider the following code:

<VideoPlayer>
  <VideoHeader>
    <h1 className="video-title">The Simpsons</h1>
  </VideoHeader>
  <VideoControls />
</VideoPlayer>

In this example, the VideoPlayer has two children: VideoHeader and VideoControls. VideoHeader, in turn, has one child: the h1 with the title content. VideoControls, on the other hand, has no children.

Why is this important? As you can see above, we can use children to compose our interface. For a more concrete example, let's say we're creating a <Panel> component that allows us to add content to it. Using a panel might look a little like this:

<Panel title="Browse for movies">
  <div>Movie stuff...</div>
  <div>Movie stuff...</div>
  <div>Movie stuff...</div>
  <div>Movie stuff...</div>
</Panel>

As you can see, we're adding content inside of the <Panel> tags. Now, how do we render that content in our component? We access it through this.props.children — a special prop that is passed to components automatically.

export default class Panel extends React.Component {
  render() {
    return (
      <div className="panel">
        <div className="panel-header">{this.props.title}</div>
        <div className="panel-body">{this.props.children}</div>
      </div>
    );
  }
}

If something like this.props.children didn't exist, we'd have to pass in all of our content through a prop, which would be very unwieldy and look really ugly:

<Panel 
  title="Browse for movies" 
  body={
    <div>
      <div>Movie stuff...</div>
      <div>Movie stuff...</div>
      <div>Movie stuff...</div>
      <div>Movie stuff...</div>
    </div>
  } 
/>

And we'd have to wrap it in an enclosing div! Thankfully, we can just nest it inside of the component like we did above, much like we nest regular HTML elements.

React.Children

Since this.props.children can have one element, multiple elements, or none at all, its value is respectively a single child node, an array of child nodes or undefined. Sometimes, we want to transform our children before rendering them — for example, to add additional props to every child. If we wanted to do that, we'd have to take the possible types of this.props.children into account. For example, if there is only one child, we can't map it.

Luckily, React provides us with a clean API to handle looping of children. If there is only one child (or none at all), it won't throw a fuss — it'll handle things for us nicely in the background.

Let's say we have a list of Movie components that are nested inside of a MovieBrowser component:

<MovieBrowser>
  <Movie title="Mad Max: Fury Road" />
  <Movie title="Harry Potter & The Goblet Of Fire" />
</MovieBrowser>

Now, let's assume for some reason that we need to pass down an extra prop to our children — the props would like to know if they are being played or not. Our MovieBrowser component would look something like this, before we added the prop:

export default class MovieBrowser extends React.Component {
  render() {
    const currentPlayingTitle = 'Mad Max: Fury Road';
    
    return (
      <div className="movie-browser">
        {this.props.children}
      </div>      
    );
  }
}

Now let's add in our isPlaying prop to the children of MovieBrowser:

export default class MovieBrowser extends React.Component {
  render() {
    const currentPlayingTitle = 'Mad Max: Fury Road';
    const childrenWithExtraProp = React.Children.map(this.props.children, child => {
      return React.cloneElement(child, {
        isPlaying: child.props.title === currentPlayingTitle
      });
    });
    
    return (
      <div className="movie-browser">
        {childrenWithExtraProp}
      </div>      
    );
  }
}

React.Children.map has two parameters: the first one is the children themselves, and the second one is a function that transforms the value of the child. In this case, we're adding an extra prop. We do that using React.cloneElement. As the first argument we pass in the child component itself, and as the second argument, we pass in any additional props. Those additional props get merged with the child's existing props, overwriting any props with the same key.

More iteration

As another example, let's say we want to wrap our components in an extra div with a special class. We also want to display the total amount of children.

export default class SomeComponent extends React.Component {
  render() {
    const childrenWithWrapperDiv = React.Children.map(this.props.children, child => {
      return (
        <div className="some-component-special-class">{child}</div> 
      );
    });
    
    return (
      <div className="some-component">
        <p>This component has {React.Children.count(this.props.children)} children.</p>
        {childrenWithWrapperDiv}        
      </div>      
    );
  }
}

Resources

View this.props.children on Learn.co and start learning to code for free.

react-this-props-children-ios-0916's People

Contributors

lukeghenco avatar thomastuts avatar annjohn avatar nikymorg avatar pletcher avatar dkennell avatar gj avatar kwebster2 avatar talum avatar

Watchers

 avatar Mat Balez avatar Victoria Thevenot avatar  avatar Joe Cardarelli avatar Taranjyot Singh avatar Sara Tibbetts avatar The Learn Team avatar Cernan Bernardo avatar Sophie DeBenedetto avatar  avatar Antoin avatar  avatar  avatar Nicole Kroese  avatar Lisa Jiang avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.