I have two calendars, such as the Agenda, have an icon calendar button, when I click on it, it will be redirected to another calendar (Planning)
, these calendars are developed with react-big-calendar, I want when I navigate for example on the week of juin 17 - 23
of Agenda and I click on the icon calendar, it will be redirected to juin 17 - 23
of the Planning.
My code is : https://codesandbox.io/s/m7k904y3o8
I try to send the date with getWeek()
, but it doesn't work.
How can I fix it ?
You can add additional data to this.props.history.push
which will then be available in the location
prop on your Planning
component. For example if you want to view the Week of the 20th December 1995:
// Agenda.js: Routing to "/planning"
this.props.history.push("/planning", { date: new Date(1994, 11, 19, 0, 0)})
// Planning.js
constructor(props) {
super(props); //Important
this.state({
/* ... */
dateWeek: this.props.location.state && this.props.location.state.date
});
}
// Following is a fix or else you would not get next/previous week.
getThisWeek = (dateWeek) => {
this.setState({ dateWeek });
}
Two other solutions I would recommend are URL parameters and Query parameters.
You should use some state management lib
My first advice would be to use Redux since the library handles situations like this very well. You want to pass some data between unrelated components. Having a state object would serve you quite well here.
The second (easier/quicker) option is to add some state management to a parent component (this is called a container). You can pass some state to each of the children as well as a setter function that you can fire from the child.
Example of your App component as a container
import React, { Component } from "react";
import autobind from 'autobind-decorator';
import { Route, Link, Switch, Redirect } from "react-router-dom";
import Agenda from "./Agenda";
import Planning from "./Planning";
class App extends Component {
state = {selectedDate: Date.now()}
@autobind
setActiveDate (dateToSet) {
this.setState({selectedDat: dateToSet});
}
/*---------------------------------------------------- Rendu -----------------------------------------------------------------*/
render() {
return (
<div>
<Switch>
<Route exact path="/" render={(props) => <Agenda {...props} setActiveDate={setActiveDate} selectedDate={this.state.selectedDate} />} />
<Route exact path="/planning" render={(props) => <Planning {...props} selectedDate={this.state.selectedDate} />}/>
</Switch>
</div>
);
}
}
export default App;
Some things to note
- first off you do not want your main app component to be used as a container in this way so please make another component to handle this state management
- The use of the
autobind
decorator is to make this easier to write, you can bind your function in the constructor if you want instead
- This component only shows half of the story, the other half is in you child components, you will need to read the date from here and also trigger the function
setActiveDate
from the child (Agenda)
Conclusion
This method will pollute your components much more than a redux implementation. But it is quicker than a full redux setup. Just try to remember the "Single responsibility principal".