Reputation: 1945
I am making a web application which I intend to make as modular as possible using reactjs.
The application consists of a menu
and an associated shopping cart
, which keeps a track of what items are put into the cart
from the menu
.
My code is:
React.render(
<div className="row">
<div className="col-md-7">
<MainMenu />
</div>
<div className="col-md-4">
<CartView />
</div>
</div>
, mountpoint
);
As it is visible, there is no hierarchical relationship between my these two components, so clearly I can't communicate by passing props
.
I read on the official React documentation:
For communication between two components that don't have a parent-child relationship, you can set up your own global event system. Subscribe to events in componentDidMount(), unsubscribe in componentWillUnmount(), and call setState() when you receive an event. Flux pattern is one of the possible ways to arrange this
However, I do not currently want to use Flux in my application.
So, my question is:
Is there any way of setting up a message passing system between the components without using Flux?
P.S: I know jQuery. I am having trouble understanding the ToDo example given on the Flux website so was just wondering if there is an alternative way of doing this.
Thanks.
Upvotes: 2
Views: 797
Reputation: 8511
Yeah you can do this without Flux. But consider Flux because it's awesome.
But if you don't want to use it, why not make them have a hierarchical relationship?
The way you'll do this is create a new root level component which you mount, which then has the <MainMenu />
and <CartView />
components as children. Provide callbacks for events on these child components which the
parent can then bind to to change it's state, which affects the props passed.
An example of this using your code as a base:
var Root = React.createClass({
getInitialState: function() {
return {
itemId: 1
}
},
mainMenuChangeHandler: function(itemId) {
if (itemId !== this.state.itemId) {
this.setState({
itemId: Number(itemId)
})
}
},
render: function() {
return (
<div className="row">
<div className="col-md-7">
<MainMenu onChange={this.mainMenuChangeHandler} />
</div>
<div className="col-md-4">
<CartView itemId={this.state.itemId} />
</div>
</div>
)
}
});
var MainMenu = React.createClass({
propTypes: {
onChange: React.PropTypes.func.isRequired
},
clickHandler: function(e) {
e.preventDefault();
this.props.onChange(e.target.href);
},
render: function() {
return (
<div>
<a href="1" onClick={this.clickHandler}>Item 1</a>
<a href="2" onClick={this.clickHandler}>Item 2</a>
</div>
);
}
});
var CartView = React.createClass({
propTypes: {
itemId: React.PropTypes.number.isRequired
},
render: function() {
var item;
if (this.props.itemId === 1) {
item = (
<div>This is Item 1 being shown</div>
);
} else if (this.props.itemId === 2) {
item = (
<div>This is Item 2 being shown</div>
);
}
return (
<div>{item}</div>
);
}
});
React.render(<Root />, mountpoint);
Upvotes: 4