【问题标题】:React Day Picker only changing "to" state on second clickReact Day Picker 仅在第二次单击时更改“to”状态
【发布时间】:2018-08-13 14:38:09
【问题描述】:

所有...我正在使用“react-day-picker”组件通过两个输入来选择日期范围。

我开始逐字使用此页面上的示例:http://react-day-picker.js.org/examples/input-from-to。我所做的唯一更改是将console.log(this.state) 添加到handleFromChangehandleToChange 方法。

该组件乍一看似乎可以工作,但是当我 console.log 状态时,我发现“to”状态仅在 second 次选择“to”日期时更新在选择器中。第一次选择“到”日期会返回“未定义”。

看看这段代码,有没有什么不正确的地方跳出来?同样,此代码由组件的创建者提供。我试图弄清楚它是组件的错误、示例代码的错误还是其他问题。

谢谢!

为方便起见,这是我正在使用的代码:

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>
    );
  }
}

【问题讨论】:

    标签: javascript reactjs react-day-picker


    【解决方案1】:

    我检查了你的代码。看起来它在状态中为 ToFrom 两个值都收到了适当的值。也许你在错误的地方有 console.log(this.state) 。

    让我告诉你,setState 方法是异步的,所以你一定得到了错误的值。

    我已在适当的状态下添加了一个 console.log 语句,以向您显示该值已正确反映。看看下面的代码

    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>
            );
        }
    }

    【讨论】:

    • 非常感谢您的回答...状态的异步特性为我提供了我需要的线索。我太直白了,试图在“handleToChange”方法的末尾触发一个方法。我应该做的并且有效的是在这个处理程序的 setState 回调中触发我的方法。那工作得很好。 (我基本上是用依赖于作为查询参数传递的“from”和“to”日期的数据填充一个表)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-06
    • 1970-01-01
    • 1970-01-01
    • 2022-11-11
    • 2021-10-28
    • 2016-02-26
    相关资源
    最近更新 更多