Reputation: 5486
Please bear with me. I just learning Reactjs and stuck at a point.
app-client.js
ReactDOM.render((
<Router history={hashHistory}>
<Route path="/" component={APP}>
<IndexRoute component={Audience}/>
<Route path="speaker" component={Speaker}/>
<Route path="board" component={Board}/>
</Route>
</Router>
), document.getElementById('react-container'));
APP.js
var APP = React.createClass({
getInitialState() {
return {
status: 'disconnected',
title: ''
}
},
emit(eventName, payload) {
this.socket.emit(eventName, payload);
},
render() {
return (
<div>
<Header title={this.state.title} status={this.state.status}/>
{this.props.children}
</div>
);
}
});
Audience.js:
var Audience = React.createClass({
render() {
return (<h1>Audience: {this.props.title}</h1>);
}
});
The page is showing all the components, but this.props.title
is not showing in the page, and the emit()
is not firing. How do I pass the props to {this.props.children}
(i.e., Audience or Speaker) on the APP?
update:
APP.js render():
render() {
const _this = this;
return (
<div>
<Header title={this.state.title} status={this.state.status}/>
{ React.children.map(this.props.children, (child, index) => {
//Get props of child
// const childProps = child.props;
//do whatever else you need, create some new props, change existing ones
//store them in variables
return React.cloneElement(child, {
// ...childProps, //these are the old props if you don't want them changed
// ...someNewProps,
// someOldPropOverwritten, //overwrite some old the old props
..._this.state,
emit: _this.emit
});
})
}
</div>
);
}
});
Upvotes: 4
Views: 750
Reputation: 351
Iterate parent element using Api React.children and clone each element using React.cloneElement
var Child = React.createClass({
render: function() {
return (<div onClick={() => this.props.doSomething(this.props.value)}>Click Me</div>);
}
});
var Audience = React.createClass({
render: function() {
return (<div>{this.props.title}</div>);
}
});
var App = React.createClass({
doSomething: function(value) {
console.log('child with value:', value);
},
render: function() {
var childrenWithProps = React.Children.map(this.props.children, (child) => React.cloneElement(child, { title: "test", doSomething: this.doSomething }));
return <div>{childrenWithProps}</div>
}
});
ReactDOM.render(
<App>
<Child value="2"/>
<Audience/>
</App>,
document.getElementById('container')
);
https://jsfiddle.net/ysq2281h/
Upvotes: 1
Reputation: 3526
There's a combination of APIs that React provides you with that will take care of exactly what you're not certain about of how to achieve ( way to pass props to components rendered by this.props.children
)
First, you need to take a look at cloneElement
It will basically take a React element, clone it, and return another with props that you can change, alter or replace entirely based on your needs.
Furthermore, combine it with the Children Utilities - loop through the children that were provided to your top level component and make the necessary changes to each element individually.
You can find a more comprehensive answer that I provided on a very similar topic for a question that was asked recently below:
changing-components-based-on-url-with-react-router
Basically, something along the lines of:
render() {
const _this = this;
return (
{React.Children.map(this.props.children, (child, index) => {
//Get props of child
const childProps = child.props;
//do whatever else you need, create some new props, change existing ones
//store them in variables
return React.cloneElement(child, {
...childProps, //these are the old props if you don't want them changed
...someNewProps,
someOldPropOverwritten, //overwrite some old the old props
..._this.state,
someFn: _this.someFn,
...
});
)}
}
Upvotes: 1