snippetjavascriptreactCritical
How can I communicate between related react components?
Viewed 0 times
relatedcommunicatereactcomponentscanhowbetween
Problem
I just got started with ReactJS and am a little stuck on a problem that I have.
My application is essentially a list with filters and a button to change the layout.
At the moment I'm using three components: `
How can I make those 3 components interact with each other, or do I need some sort of global data model where I can just make changes to?
My application is essentially a list with filters and a button to change the layout.
At the moment I'm using three components: `
, and , now obviously when I change settings in I want to trigger some method in ` to update my view.How can I make those 3 components interact with each other, or do I need some sort of global data model where I can just make changes to?
Solution
The best approach would depend on how you plan to arrange those components. A few example scenarios that come to mind right now:
There may be other scenarios that I'm not thinking of. If yours doesn't fit within these, then let me know. Here are some very rough examples of how I've been handling the first two scenarios:
Scenario #1
You could pass a handler from
var Filters = React.createClass({
handleFilterChange: function() {
var value = this.refs.filterInput.getDOMNode().value;
this.props.updateFilter(value);
},
render: function() {
return ;
}
});
var List = React.createClass({
getInitialState: function() {
return {
listItems: ['Chicago', 'New York', 'Tokyo', 'London', 'San Francisco', 'Amsterdam', 'Hong Kong'],
nameFilter: ''
};
},
handleFilterUpdate: function(filterValue) {
this.setState({
nameFilter: filterValue
});
},
render: function() {
var displayedItems = this.state.listItems.filter(function(item) {
var match = item.toLowerCase().indexOf(this.state.nameFilter.toLowerCase());
return (match !== -1);
}.bind(this));
var content;
if (displayedItems.length > 0) {
var items = displayedItems.map(function(item) {
return
});
content = {items}
} else {
content =
No items matching this filter;
}
return (
Results
{content}
);
}
});
React.renderComponent(, document.body);
var Filters = React.createClass({
handleFilterChange: function() {
var value = this.refs.filterInput.getDOMNode().value;
this.props.updateFilter(value);
},
render: function() {
return ;
}
});
var List = React.createClass({
render: function() {
var content;
if (this.props.items.length > 0) {
var items = this.props.items.map(function(item) {
return
});
content = {items}
} else {
content =
No items matching this filter;
}
return (
Results
{content}
);
}
});
var ListContainer = React.createClass({
getInitialState: function() {
return {
listItems: ['Chicago', 'New York', 'Tokyo', 'London', 'San Francisco', 'Amsterdam', 'Hong Kong'],
nameFilter: ''
};
},
handleFilterUpdate: function(filterValue) {
this.setState({
nameFilter: filterValue
});
},
render: function() {
var displayedItems = this.state.listItems.filter(function(item) {
var match = item.toLowerCase().indexOf(this.state.nameFilter.toLowerCase());
return (match !== -1);
}.bind(this));
return (
);
}
});
React.renderComponent(, document.body);
`
Scenario #3
When the components can't communicate between any sort of parent-child relationship, the documentation recommends setting up a global event system.
- `
is a child component of
- Both
andare children of a parent component
andlive in separate root components entirely.
There may be other scenarios that I'm not thinking of. If yours doesn't fit within these, then let me know. Here are some very rough examples of how I've been handling the first two scenarios:
Scenario #1
You could pass a handler from
to , which could then be called on the onChange event to filter the list with the current value.
JSFiddle for #1 →
/** @jsx React.DOM */var Filters = React.createClass({
handleFilterChange: function() {
var value = this.refs.filterInput.getDOMNode().value;
this.props.updateFilter(value);
},
render: function() {
return ;
}
});
var List = React.createClass({
getInitialState: function() {
return {
listItems: ['Chicago', 'New York', 'Tokyo', 'London', 'San Francisco', 'Amsterdam', 'Hong Kong'],
nameFilter: ''
};
},
handleFilterUpdate: function(filterValue) {
this.setState({
nameFilter: filterValue
});
},
render: function() {
var displayedItems = this.state.listItems.filter(function(item) {
var match = item.toLowerCase().indexOf(this.state.nameFilter.toLowerCase());
return (match !== -1);
}.bind(this));
var content;
if (displayedItems.length > 0) {
var items = displayedItems.map(function(item) {
return
- {item};
});
content = {items}
} else {
content =
No items matching this filter;
}
return (
Results
{content}
);
}
});
React.renderComponent(, document.body);
Scenario #2
Similar to scenario #1, but the parent component will be the one passing down the handler function to , and will pass the filtered list to . I like this method better since it decouples the from the .
JSFiddle for #2 →
/** @jsx React.DOM */var Filters = React.createClass({
handleFilterChange: function() {
var value = this.refs.filterInput.getDOMNode().value;
this.props.updateFilter(value);
},
render: function() {
return ;
}
});
var List = React.createClass({
render: function() {
var content;
if (this.props.items.length > 0) {
var items = this.props.items.map(function(item) {
return
- {item};
});
content = {items}
} else {
content =
No items matching this filter;
}
return (
Results
{content}
);
}
});
var ListContainer = React.createClass({
getInitialState: function() {
return {
listItems: ['Chicago', 'New York', 'Tokyo', 'London', 'San Francisco', 'Amsterdam', 'Hong Kong'],
nameFilter: ''
};
},
handleFilterUpdate: function(filterValue) {
this.setState({
nameFilter: filterValue
});
},
render: function() {
var displayedItems = this.state.listItems.filter(function(item) {
var match = item.toLowerCase().indexOf(this.state.nameFilter.toLowerCase());
return (match !== -1);
}.bind(this));
return (
);
}
});
React.renderComponent(, document.body);
`
Scenario #3
When the components can't communicate between any sort of parent-child relationship, the documentation recommends setting up a global event system.
Context
Stack Overflow Q#21285923, score: 352
Revisions (0)
No revisions yet.