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?
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With