Reputation: 259
Imagine that Component A creates a list of items that Component B needs to display. What's the proper way to pass data from Component A to Component B from their parent?
For example, let's say that Component A's constructor creates a list of items and has a function _getListItems()
that returns that list. I'm hoping the parent can then pass that list on to other components via props.
My naive (non-working) implementation has their parent attempting to render the components like this:
render () {
return (
<div>
<h1>Data Test</h1>
<ComponentA ref='compa'/>
<ComponentB items={this.refs.compa._getListItems()}/>
</div>
);
}
....although the code above doesn't work, I hope it illustrates what I'm trying to do.
ps. nOOb to react and javascript, so forgive me if the answer to my question's obvious...
Upvotes: 1
Views: 1254
Reputation: 259
Following the accepted answer above, I've just had a (related) EUREKA moment, so I'm going to expand on the answer; when the parent uses its own state to pass props to its children, whenever the parent's state changes, its render() function is called, thus updating the children with the updated state. So you can do stuff like this:
class MyContainer extends React.Component {
constructor(props) {
super(props);
let sltd = this.props.selected
this.state = {
stuff: [1,2,3],
selected: sltd
};
}
_handleAStuff(value) {
this.setState(selected: value)
//do other stuff with selected...
}
_handleBStuff(value) {
this.setState(selected: value)
//do other stuff with selected...
}
render() {
return (
<div>
<ComponentA items={this.state.stuff} selected={this.state.selected} parentFunc={this._handleAStuff.bind(this)} />
<ComponentB items={this.state.stuff} selected={this.state.selected} parentFunc={this._handleBStuff.bind(this)} />
</div>
);
}
}
MyContainer.defaultProps = {
selected: 0
}
class ComponentA extends React.Component {
constructor(props) {
super(props)
}
_handleSelect(value) {
this.props.parentFunc(value.label)
}
render() {
const itm = this.props.items.map(function(values) {
return { value: values, label: values}
})
return (
<div>
<Select
options={itm}
value={this.props.selected}
onChange={this._handleSelect.bind(this)}
/>
</div>
);
}
}
// ComponentB...
The callback pattern above means that ComponentA and ComponentB do not need to maintain state, they simply 'render stuff', which is also pretty cool. I'm beginning to see the power of REACT...
Upvotes: 0
Reputation: 7672
Divide your components into two separate categories.
https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0#.skmxo7vt4
So, in your case the data should created by parent of ComponentA
and ComponentB
and pass the data to both ComponentA
and ComponentB
via props.
Example:
render(){
let items = this._getListItems();
return (
<div>
<ComponentA items={items} />
<ComponentB items={items} />
</div>
);
}
Rewrite OP's approach in the comment:
class MyContainer extends React.Component {
constructor(props) {
super(props);
this.state = { stuff: [1,2,3] };
}
render() {
return (
<div>
<ComponentA items={this.state.stuff} />
<ComponentB items={this.state.stuff} />
</div>
);
}
}
Upvotes: 2