Dynamically add child components in React Dynamically add child components in React reactjs reactjs

Dynamically add child components in React


You need to pass your components as children, like this:

var App = require('./App.js');var SampleComponent = require('./SampleComponent.js');ReactDOM.render(    <App>        <SampleComponent name="SomeName"/>     <App>,     document.body);

And then append them in the component's body:

var App = React.createClass({    render: function() {        return (            <div>                <h1>App main component! </h1>                {                    this.props.children                }            </div>        );    }});

You don't need to manually manipulate HTML code, React will do that for you. If you want to add some child components, you just need to change props or state it depends. For example:

var App = React.createClass({    getInitialState: function(){        return [            {id:1,name:"Some Name"}        ]    },    addChild: function() {        // State change will cause component re-render        this.setState(this.state.concat([            {id:2,name:"Another Name"}        ]))    }    render: function() {        return (            <div>                <h1>App main component! </h1>                <button onClick={this.addChild}>Add component</button>                {                    this.state.map((item) => (                        <SampleComponent key={item.id} name={item.name}/>                    ))                }            </div>        );    }});


First, I wouldn't use document.body. Instead add an empty container:

index.html:

<html>    <head></head>    <body>        <div id="app"></div>    </body></html>

Then opt to only render your <App /> element:

main.js:

var App = require('./App.js');ReactDOM.render(<App />, document.getElementById('app'));

Within App.js you can import your other components and ignore your DOM render code completely:

App.js:

var SampleComponent = require('./SampleComponent.js');var App = React.createClass({    render: function() {        return (            <div>                <h1>App main component!</h1>                <SampleComponent name="SomeName" />            </div>        );    }});

SampleComponent.js:

var SampleComponent = React.createClass({    render: function() {        return (            <div>                <h1>Sample Component!</h1>            </div>        );    }});

Then you can programmatically interact with any number of components by importing them into the necessary component files using require.


Sharing my solution here, based on Chris' answer. Hope it can help others.

I needed to dynamically append child elements into my JSX, but in a simpler way than conditional checks in my return statement. I want to show a loader in the case that the child elements aren't ready yet. Here it is:

export class Settings extends React.PureComponent {  render() {    const loading = (<div>I'm Loading</div>);    let content = [];    let pushMessages = null;    let emailMessages = null;    if (this.props.pushPreferences) {       pushMessages = (<div>Push Content Here</div>);    }    if (this.props.emailPreferences) {      emailMessages = (<div>Email Content Here</div>);    }    // Push the components in the order I want    if (emailMessages) content.push(emailMessages);    if (pushMessages) content.push(pushMessages);    return (      <div>        {content.length ? content : loading}      </div>    )}

Now, I do realize I could also just put {pushMessages} and {emailMessages} directly in my return() below, but assuming I had even more conditional content, my return() would just look cluttered.