My scenario is that I'm creating a render() function in a controller (not React related) to render views with the option of specifying a layout. That way I can have multiple different layout components, all accepting a content property, that can be rendered in a simple way. Here's what I'm trying to do in a nutshell:
render: function(content, layout) {
layout = layout || <Layout />;
layout.setProps({ content: content });
React.render(layout, document.body);
}
Can it be done? Or if you think it can be done but it's a bad idea, please let me know why.
cloneElement() method used here. This method is used to create the clone of the element that will be given as an argument, also here we can pass props and children as arguments. Here variable “c” is passed as an element in React. cloneElement() method for cloning, also passed props {name1: “C++”, name2: “JAVA”}.
You can use any logic and conditionals in order to build the object. You will most commonly use the ternary operator to add conditional attributes to an element in React.
One of the ways we can add new props to the children is by using React. cloneElement() like so: const newProps = { className: 'hidden', onClick: () => alert('test') }; const MyComponent = ({ children }) => ( <div> {children. map(child => React.
A component cannot update its own props unless they are arrays or objects (having a component update its own props even if possible is an anti-pattern), but can update its state and the props of its children.
There are a couple ways you could approach this.
The simplest is to pass the layout's type and properties separately:
function render(content, layoutType, layoutProperties) {
layoutType = layoutType || Layout;
layoutProperties = layoutProperties || {};
var props = { content: content };
for (var key in layoutProperties) {
props[key] = layoutProperties[key];
}
var layout = React.createElement(layoutType, props);
React.render(layout, document.body);
}
render(<div>Test 1</div>);
render(<div>Test 2</div>, CustomLayout, { title: "Test Title" });
JSFiddle example: http://jsfiddle.net/BinaryMuse/hjLufbkz/
If you want to pass a fully-realized ReactElement
as the layout instead, you could use React.addons.cloneWithProps
(or, in v0.13 RC2 and later, React.cloneElement
):
function render(content, layout) {
var props = { content: content };
layout = layout || <Layout />;
layout = React.addons.cloneWithProps(layout, props);
React.render(layout, document.body);
}
render(<div>Test 1</div>);
render(<div>Test 2</div>, <CustomLayout title="Test Title" />);
JSFiddle example: http://jsfiddle.net/BinaryMuse/8krawhx4/
I'm a big fan of using this.props.children
to nest elements; note that you can modify both the techniques above to do so:
function render(content, layoutType, layoutProperties) {
layoutType = layoutType || Layout;
layoutProperties = layoutProperties || {};
var layout = React.createElement(layoutType, layoutProperties, content);
React.render(layout, document.body);
}
JSFiddle example: http://jsfiddle.net/BinaryMuse/6g8uyfp4/
and
function render(content, layout) {
layout = layout || <Layout>{content}</Layout>;
layout = React.addons.cloneWithProps(layout, {children: content});
React.render(layout, document.body);
}
JSFiddle example: http://jsfiddle.net/BinaryMuse/nadv297h/
Of course, if one of your custom layout components already utilizes this.props.children
for other purposes, the original technique with cloneWithProps
/cloneElement
and this.props.content
works just fine. (JSFiddle example: http://jsfiddle.net/BinaryMuse/b5ncfnqh/)
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