ismay ismay - 5 months ago 8
Javascript Question

Can a react component have multiple areas for child content?

Let's say I have a simple react component:

import React from 'react';
import styles from "./index.css";

export default React.createClass({
render: function() {
return (
<header className={styles.root}>
// area for child content
{this.props.children}
</header>
);
}
});


Now let's say that instead of one area for any child components, I'd want two, like so:

import React from 'react';
import styles from "./index.css";

export default React.createClass({
render: function() {
return (
<header className={styles.root}>
<div className={styles.logo}>
// logo children here
</div>
<div>
// navigation children here
</div>
</header>
);
}
});


I know that I could use attributes, but that wouldn't be very elegant for a large chunk of html content. How can this be done in react in a way that's similar to, for example, the named blocks in swig?




Example of named blocks:

{% extends 'layout.html' %}

{% block title %}My Page{% endblock %}

{% block head %}
{% parent %}
<link rel="stylesheet" href="custom.css">
{% endblock %}

{% block content %}
<p>This is just an awesome page.</p>
{% endblock %}


You see that these blocks can be used by referring to their name, and thus allow to 'yield' multiple areas of content. I'm hoping that there is a similarly elegant way in react to do this, as it makes components very composable.

Answer
Make seperate components Donot use props to pass components as children.
something like this.

//header.js

import React from 'react';
import styles from "./index.css";

export default React.createClass({
  getComponent(key) {
     return this.props.children.filter( (comp) => {
             return comp.key === key;
     });
  }
  render: function() {
    return (
      <header className={styles.root}>
        <div className={styles.logo}>
          {this.getComponent('logo')}
        </div>
        <div>
         {this.getComponent('navbar'}

        </div>
      </header>
    );
  }
});

//app.js

export default React.createClass({
      render: function() {
        return (
          <Header>
            <Logo key="logo"/>
            <Navbar key="navbar"/>
          </Header>
        );
      }
    });