How to send the date state of calendar to another

2020-04-21 03:32发布

问题:

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 ?

回答1:

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.



回答2:

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".