简体   繁体   English

React Day Picker 只在第二次点击时改变“to”状态

[英]React Day Picker only changing "to" state on second click

all...I'm using the 'react-day-picker' component to choose a range of dates via two inputs.全部...我正在使用“react-day-picker”组件通过两个输入选择日期范围。

I started by using, verbatim, the example on this page: http://react-day-picker.js.org/examples/input-from-to .我开始逐字使用此页面上的示例: http : //react-day-picker.js.org/examples/input-from-to The only alterations I made was the add console.log(this.state) to the handleFromChange and handleToChange methods.我所做的唯一更改是将console.log(this.state)添加到handleFromChangehandleToChange方法。

The component seems to work at first glance, but when I console.log the state, I found that the "to" state is only being updated the second time a "to" date is selected in the picker.该组件乍一看似乎可以工作,但是当我 console.log 状态时,我发现“to”状态仅在第二次在选择器中选择“to”日期时更新。 Selecting a "to" date the first time returns "undefined."第一次选择“到”日期会返回“未定义”。

Looking at this code, is there anything that jumps out as incorrect?看看这段代码,有没有什么跳出来的错误? Again, this code was provided by the creator of the component.同样,此代码是由组件的创建者提供的。 I'm trying to figure out if its a bug with the component, a bug with the example code, or some other problem.我试图弄清楚它是组件的错误,示例代码的错误还是其他问题。

Thanks!谢谢!

For convenience, here's the code I'm using:为方便起见,这是我正在使用的代码:

import React from 'react';
import moment from 'moment';
import Helmet from 'react-helmet';

import DayPickerInput from 'react-day-picker/DayPickerInput';
import 'react-day-picker/lib/style.css';

import { formatDate, parseDate } from 'react-day-picker/moment';

export default class Example extends React.Component {
  constructor(props) {
    super(props);
    this.handleFromChange = this.handleFromChange.bind(this);
    this.handleToChange = this.handleToChange.bind(this);
    this.state = {
      from: undefined,
      to: undefined,
    };
  }
  componentWillUnmount() {
    clearTimeout(this.timeout);
  }
  focusTo() {
    // Focus to `to` field. A timeout is required here because the overlays
    // already set timeouts to work well with input fields
    this.timeout = setTimeout(() => this.to.getInput().focus(), 0);
  }
  showFromMonth() {
    const { from, to } = this.state;
    if (!from) {
      return;
    }
    if (moment(to).diff(moment(from), 'months') < 2) {
      this.to.getDayPicker().showMonth(from);
    }
  }
  handleFromChange(from) {
    // Change the from date and focus the "to" input field
    this.setState({ from }, () => {
      if (!this.state.to) {
        this.focusTo();
      }
    });
  }
  handleToChange(to) {
    this.setState({ to }, this.showFromMonth);
  }
  render() {
    const { from, to } = this.state;
    const modifiers = { start: from, end: to };
    return (
      <div className="InputFromTo">
        <DayPickerInput
          value={from}
          placeholder="From"
          format="LL"
          formatDate={formatDate}
          parseDate={parseDate}
          dayPickerProps={{
            selectedDays: [from, { from, to }],
            disabledDays: { after: to },
            toMonth: to,
            modifiers,
            numberOfMonths: 2,
          }}
          onDayChange={this.handleFromChange}
        />{' '}
        —{' '}
        <span className="InputFromTo-to">
          <DayPickerInput
            ref={el => (this.to = el)}
            value={to}
            placeholder="To"
            format="LL"
            formatDate={formatDate}
            parseDate={parseDate}
            dayPickerProps={{
              selectedDays: [from, { from, to }],
              disabledDays: { before: from },
              modifiers,
              month: from,
              fromMonth: from,
              numberOfMonths: 2,
            }}
            onDayChange={this.handleToChange}
          />
        </span>
        <Helmet>
          <style>{`
  .InputFromTo .DayPicker-Day--selected:not(.DayPicker-Day--start):not(.DayPicker-Day--end):not(.DayPicker-Day--outside) {
    background-color: #f0f8ff !important;
    color: #4a90e2;
  }
  .InputFromTo .DayPicker-Day {
    border-radius: 0 !important;
  }
  .InputFromTo .DayPicker-Day--start {
    border-top-left-radius: 50% !important;
    border-bottom-left-radius: 50% !important;
  }
  .InputFromTo .DayPicker-Day--end {
    border-top-right-radius: 50% !important;
    border-bottom-right-radius: 50% !important;
  }
  .InputFromTo .DayPickerInput-Overlay {
    width: 550px;
  }
  .InputFromTo-to .DayPickerInput-Overlay {
    margin-left: -198px;
  }
`}</style>
        </Helmet>
      </div>
    );
  }
}

I checked your code.我检查了你的代码。 It looks like it receives proper value in the state for both the two value To and From .看起来它在状态中为两个值ToFrom都收到了正确的值。 Maybe you have console.log(this.state) at the wrong place.也许你在错误的地方有 console.log(this.state) 。

Let me tell you that setState method is asynchronous so you must be getting the wrong values.让我告诉你setState方法是异步的,所以你一定得到了错误的值。

I've added a console.log statement at appropriate state to show you that the value is reflected right.我在适当的状态添加了一个 console.log 语句,以向您表明该值反映正确。 Have a look at below code看看下面的代码

 import React from 'react'; import moment from 'moment'; import Helmet from 'react-helmet'; import DayPickerInput from 'react-day-picker/DayPickerInput'; import 'react-day-picker/lib/style.css'; import { formatDate, parseDate } from 'react-day-picker/moment'; export default class Example extends React.Component { constructor(props) { super(props); this.handleFromChange = this.handleFromChange.bind(this); this.handleToChange = this.handleToChange.bind(this); this.state = { from: undefined, to: undefined, }; } componentWillUnmount() { clearTimeout(this.timeout); } focusTo() { // Focus to `to` field. A timeout is required here because the overlays // already set timeouts to work well with input fields this.timeout = setTimeout(() => this.to.getInput().focus(), 0); } showFromMonth() { console.log("value from the state",this.state); const { from, to } = this.state; if (!from) { return; } if (moment(to).diff(moment(from), 'months') < 2) { this.to.getDayPicker().showMonth(from); } } handleFromChange(from) { console.log("New From value", from); // Change the from date and focus the "to" input field this.setState({ from }, () => { console.log("value from the state",this.state); if (!this.state.to) { this.focusTo(); } }); } handleToChange(to) { console.log("New To value", to); this.setState({ to }, this.showFromMonth); } render() { const { from, to } = this.state; const modifiers = { start: from, end: to }; return ( <div className="InputFromTo"> <DayPickerInput value={from} placeholder="From" format="LL" formatDate={formatDate} parseDate={parseDate} dayPickerProps={{ selectedDays: [from, { from, to }], disabledDays: { after: to }, toMonth: to, modifiers, numberOfMonths: 2, }} onDayChange={this.handleFromChange} />{' '} —{' '} <span className="InputFromTo-to"> <DayPickerInput ref={el => (this.to = el)} value={to} placeholder="To" format="LL" formatDate={formatDate} parseDate={parseDate} dayPickerProps={{ selectedDays: [from, { from, to }], disabledDays: { before: from }, modifiers, month: from, fromMonth: from, numberOfMonths: 2, }} onDayChange={this.handleToChange} /> </span> <Helmet> <style>{` .InputFromTo .DayPicker-Day--selected:not(.DayPicker-Day--start):not(.DayPicker-Day--end):not(.DayPicker-Day--outside) { background-color: #f0f8ff !important; color: #4a90e2; } .InputFromTo .DayPicker-Day { border-radius: 0 !important; } .InputFromTo .DayPicker-Day--start { border-top-left-radius: 50% !important; border-bottom-left-radius: 50% !important; } .InputFromTo .DayPicker-Day--end { border-top-right-radius: 50% !important; border-bottom-right-radius: 50% !important; } .InputFromTo .DayPickerInput-Overlay { width: 550px; } .InputFromTo-to .DayPickerInput-Overlay { margin-left: -198px; } `}</style> </Helmet> </div> ); } }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM