Reputation: 63
I'm using pure React with a Rails API backend.
I am fetching data from API and storing state in my Trips component. I have a Link component where I am able to pass the state to my NewTrip component, however <Link>
does not allow me to pass functions.
I am able to pass functions to NewPage via render method on the Route component located at './routes/Index'.
But how do I pass the function from my Trips component? It's so much easier when passing as props to the component, the Router seems to be in the way!
'routes/Index.js'
export default (
<Router>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/trips" exact component={Trips} />
<Route path="/trip" render={(routeProps)=><NewTrip {...routeProps} />}/>
<Route path="/trip/:id" exact component={Trip} />
<Route path="/trip/:id/cost" exact component={NewCost} />
<Route path="/trip/:id/edit" exact component={EditTrip} />
</Switch>
</Router>
);
'components/Trips'
class Trips extends React.Component {
constructor(props) {
super(props);
this.state = {
trips: []
}
this.addTrip = this.addTrip.bind(this);
}
addTrip(trip) {
const {trips} = this.state;
trips.push(trip);
this.setState({ trips: trips});
}
render(){
return(
<Link
to={{
pathname: "/trip",
state: {trips: trips, onAddTrip={this.addTrip}} // not allowed,
// but I want to pass this function to the
// Component which is rendered by the Route in Index.js
}}
className="btn custom-button">
Create New Trip
</Link>
)
}
}
Upvotes: 2
Views: 754
Reputation: 3253
You can pass functions using state
in react router Link.
<Link
to={{
pathname: "/trip",
state: {trips: trips, onAddTrip: this.addTrip}
}}
className="btn custom-button">
Create New Trip
</Link>
And then in /trip
, you retrieve and use the function like this:
this.props.location.state.addTrip();
Upvotes: 0
Reputation: 1788
I think you should lift state up of the Trips
component and have it in your 'routes/Index.js'. (it will need to be a component now, not just an export).
'routes/Index.js'
export default class Routes extends React.Component {
constructor(props) {
super(props);
this.state = {
trips: []
}
this.addTrip = this.addTrip.bind(this);
}
addTrip(trip) {
const {trips} = this.state;
trips.push(trip);
this.setState({ trips: trips});
}
render() {
return (
<Router>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/trips" exact component={Trips} />
<Route path="/trip" render={(routeProps)=>
<NewTrip addTrip={this.addTrip} trips={this.state.trips} {...routeProps} />
}/>
<Route path="/trip/:id" exact render={(routeProps)=>
<Trip addTrip={this.addTrip} trips={this.state.trips} {...routeProps} />
}/>
<Route path="/trip/:id/cost" exact component={NewCost} />
<Route path="/trip/:id/edit" exact component={EditTrip} />
</Switch>
</Router>
);
}
}
'components/Trips'
class Trips extends React.Component {
render() {
const trips = this.props.trips
return (
<Link
to={{
pathname: "/trip",
}}
className="btn custom-button">
Create New Trip
</Link>
)
}
}
It might be better to have the state even higher up in the App
component, but you didn't provide that, so this has to do :)
Upvotes: 2