Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically nesting React.js components

Tags:

reactjs

I'd like to create a flexible/dynamic JSX form format that can be rendered using React.js. This format has to include nested groups. A group can contain other groups as well as questions.

var Group = React.createClass({
    render: function(){
        return (
            <fieldset></fieldset>
        );
    }
});

var Text = React.createClass({
    render: function() {
        return (
            <label>
               <input type="text"/>
           </label>
        );
     }
});

React.render(
    <form>
        <Group>
           <Text/>
        </Group>
        <Text/>
    </form>,
    document.getElementById('container')
);

I want to produce:

<form>
    <fieldset>
        <label>
            <input type="text">
        </label>
    </fieldset>
    <label>
        <input type="text">
    </label>
</form>

However the <fieldset> element is not populated. The output just contains an empty <fieldset>.

How should I nest react.js components, and still maintain the flexibility of re-using question and group components at root and nested levels?

like image 462
Martijn van de Rijdt Avatar asked Mar 12 '15 21:03

Martijn van de Rijdt


People also ask

Can React components be nested?

In React, we can nest components inside within one another. This helps in creating more complex User Interfaces. The components that are nested inside parent components are called child components.

How do you render a component dynamically based on a JSON config?

To render the components based on the component key in the JSON config, we first need to create an object that maps the components with the component key. As you can see, I have mapped the component key with the corresponding Reactstrap component. At the top, we will import all the required components.

What is dynamic rendering React?

Dynamic component rendering with ReactTo allow us to render a JSON by dynamic components using their name we first have to loop through the array of components itself. Below you can see that we're using the map function to do exactly that.


2 Answers

When you nest React elements into other React elements in JSX, the parent element gets passed a children prop that contains the children elements. See Type of the Children props.

Another way to look at it is that <Group><div></div></Group> is the JSX equivalent to React.createElement(Group, null, React.createElement('div', null)), which is in turn equivalent to React.createElement(Group, {children: React.createElement('div', null)}).

So in your case, your Group component would look like:

var Group = React.createClass({
    render: function(){
        return (
            <fieldset>{this.props.children}</fieldset>
        );
    }
});

Note that the children props is an opaque data structure (it might be a single element or an array of elements depending on the input), so if you ever need to manipulate it, you should use the React.Children API.

like image 101
Alexandre Kirszenberg Avatar answered Nov 03 '22 18:11

Alexandre Kirszenberg


If anyone else is having trouble debugging through this as well and just in case the top-voted answer doesn't work for them, the docs say that User defined components must be capitalized.
So in your case, if you import your fieldset controller as Fieldset instead, everything should work just fine.

like image 36
Scrotch Avatar answered Nov 03 '22 18:11

Scrotch