I'm trying to pass a dynamic state to all the routes in a React router, specifically a shopping cart (an array of objects).
The layout is I have a parent component which contains the router and all the routes, and in that I want to store the cart in state and pass it to the routes (so essentially all routes will have access to it). I've been trying a few different things and troubleshooting it by looking it up on forums for a while but I just can't get it. This is the latest setup I have:
- Main.jsx
// This is the app entry point
import React, { Component } from 'react';
import { render } from 'react-dom';
import RouterHub from './RouterHub.jsx';
render((
<RouterHub />
), document.getElementById('root'));
- RouterHub.jsx
import React, { Component } from 'react';
import { render } from 'react-dom';
import { Router, Route, hashHistory } from 'react-router'
import Home from './Home.jsx';
import Dogs from './Pages/Other.jsx';
class RouterHub extends Component {
constructor(props) {
super(props);
this.addItem = this.addItem.bind(this);
this.state = {
cart: []
};
}
addItem(item) {
let newCart = this.state.cart.splice();
newCart.push(item);
this.setState({cart: newCart});
}
render() {
return(
<Router history={hashHistory}>
<Route path="/" component={Home} cart={this.state.cart} addItem={this.addItem} />
<Route path="/other" component={Other} cart={this.state.cart} addItem={this.addItem}/>
</Router>
);
}
}
export default RouterHub;
- Home.jsx
import React, { Component } from 'react';
import Slideshow from './Home/Slideshow.jsx';
import Navbar from './Constants/Navbar.jsx';
import Footer from './Constants/Footer.jsx';
class Home extends Component {
constructor(props) {
super(props);
}
render() {
return(
<div>
<button onClick={() => this.props.route.addItem('potato')}>click me</button>
<Navbar />
// All the JSX content, I've removed to make it succint
<Footer />
</div>
);
}
}
export default Home;
Essentially what I'm wanting is in Home.jsx, when I click that button, I want another potato added to the cart. However, with this setup I get the error:
bundle.js:46451 Warning: [react-router] You cannot change <Router routes>; it will be ignored
How do I get it so that updating state in the RouterHub passes that to the routes, or is that not possible and I'm doing this all the wrong way?
Thanks for any help
Since you already have a main component for holding your state, you should insert that in the top level Route component something like this:
Then in your RouterHub component, pass those clone each children components with props, something like this:
Bumping into this kind of problems will make you think of using some state management libraries like Redux/Flux.