反应日期选择器
React Datepicker
我正在尝试创建一个小型日历计算器,它可以减去两个日期并给出天数。
为此,我选择了图书馆 react-datepicker
。
现在我遇到一个问题,state
单击后更新。这意味着当我第二次选择日期时,我会得到前一个的结果。
此外,我不明白为什么当我取消注释 ...this.state
以保存 state
的不变性时它停止更新。
有我的代码
import React, { Component } from 'react';
import DatePicker from 'react-datepicker';
import moment from 'moment';
import 'react-datepicker/dist/react-datepicker.css';
import CalendarInput from '../../UI/CalendarInput/CalendarInput';
class CalendarPage extends Component {
constructor(props) {
super(props);
this.state = {
startDate: moment(),
endDate: moment(),
days: 0
};
this.handleChangeEnd = this.handleChangeEnd.bind(this);
this.handleChangeStart = this.handleChangeStart.bind(this);
this.daysLeft = this.daysLeft.bind(this);
}
daysLeft() {
let {startDate, endDate} = this.state;
console.log(startDate);
console.log(endDate);
let amount = endDate.diff(startDate, 'days');
this.setState({
// ...this.state,
days: amount
});
}
handleChangeStart(date) {
this.setState({
// ...this.state,
startDate: date
});
this.daysLeft();
}
handleChangeEnd(date) {
this.setState({
// ...this.state,
endDate: date
});
this.daysLeft();
}
render() {
return (
<div>
<h2 className="pl-2 mb-4">
Calendar
</h2>
<div className="row no-gutters calculator-container">
<DatePicker
selected={this.state.startDate}
selectsStart
startDate={this.state.startDate}
endDate={this.state.endDate}
onChange={this.handleChangeStart}
customInput={<CalendarInput label="departure"/>}
/>
<DatePicker
selected={this.state.endDate}
selectsEnd
startDate={this.state.startDate}
endDate={this.state.endDate}
onChange={this.handleChangeEnd}
customInput={<CalendarInput label="arrival"/>}
/>
<div className="amount">
{this.state.days}
</div>
</div>
</div>
);
}
}
export default CalendarPage;
您在一个周期内多次调用 setState
,并在同一周期内引用 this.state
。 setState
不保证在您调用时更新状态对象,但在稍后的某个时间。
因此,您对 this.daysLeft()
的调用将访问先前的状态,而不是您预期的 setState
调用的结果。
setState
有两种模式,一种是提供一个对象,稍后浅合并,另一种是状态可以更新时调用的回调函数。您可能需要使用后一种形式,以便您可以保证按顺序完成状态更改。如果您阅读文档,后者实际上是首选模式,对象形式是为了在简单的代码路径中提供方便,而且我认为从历史上看,它已经出现在很多教程中,这会导致混淆。
看看这是否有帮助,如果您修改了代码但仍然有问题,请回来。 Post 你修改后的代码,如果你这样做的话。
React may batch multiple setState() calls into a single update for
performance.
这意味着:
handleChangeStart(date) {
// this update will not be executed directly...
this.setState({
startDate: date
});
this.daysLeft();
}
daysLeft() {
// previous setState didn't yet take effect, so we access an old startDate
let {startDate, endDate} = this.state;
console.log(startDate);
console.log(endDate);
let amount = endDate.diff(startDate, 'days');
this.setState({
days: amount
});
}
您可以通过以下方式修复它:
handleChangeStart(date) {
this.setState(prevState => {
return {
startDate: date,
days: this.daysLeft(date, prevState.endDate),
}
});
}
daysLeft(startDate, endDate) {
return endDate.diff(startDate, 'days');
}
我正在尝试创建一个小型日历计算器,它可以减去两个日期并给出天数。
为此,我选择了图书馆 react-datepicker
。
现在我遇到一个问题,state
单击后更新。这意味着当我第二次选择日期时,我会得到前一个的结果。
此外,我不明白为什么当我取消注释 ...this.state
以保存 state
的不变性时它停止更新。
有我的代码
import React, { Component } from 'react';
import DatePicker from 'react-datepicker';
import moment from 'moment';
import 'react-datepicker/dist/react-datepicker.css';
import CalendarInput from '../../UI/CalendarInput/CalendarInput';
class CalendarPage extends Component {
constructor(props) {
super(props);
this.state = {
startDate: moment(),
endDate: moment(),
days: 0
};
this.handleChangeEnd = this.handleChangeEnd.bind(this);
this.handleChangeStart = this.handleChangeStart.bind(this);
this.daysLeft = this.daysLeft.bind(this);
}
daysLeft() {
let {startDate, endDate} = this.state;
console.log(startDate);
console.log(endDate);
let amount = endDate.diff(startDate, 'days');
this.setState({
// ...this.state,
days: amount
});
}
handleChangeStart(date) {
this.setState({
// ...this.state,
startDate: date
});
this.daysLeft();
}
handleChangeEnd(date) {
this.setState({
// ...this.state,
endDate: date
});
this.daysLeft();
}
render() {
return (
<div>
<h2 className="pl-2 mb-4">
Calendar
</h2>
<div className="row no-gutters calculator-container">
<DatePicker
selected={this.state.startDate}
selectsStart
startDate={this.state.startDate}
endDate={this.state.endDate}
onChange={this.handleChangeStart}
customInput={<CalendarInput label="departure"/>}
/>
<DatePicker
selected={this.state.endDate}
selectsEnd
startDate={this.state.startDate}
endDate={this.state.endDate}
onChange={this.handleChangeEnd}
customInput={<CalendarInput label="arrival"/>}
/>
<div className="amount">
{this.state.days}
</div>
</div>
</div>
);
}
}
export default CalendarPage;
您在一个周期内多次调用 setState
,并在同一周期内引用 this.state
。 setState
不保证在您调用时更新状态对象,但在稍后的某个时间。
因此,您对 this.daysLeft()
的调用将访问先前的状态,而不是您预期的 setState
调用的结果。
setState
有两种模式,一种是提供一个对象,稍后浅合并,另一种是状态可以更新时调用的回调函数。您可能需要使用后一种形式,以便您可以保证按顺序完成状态更改。如果您阅读文档,后者实际上是首选模式,对象形式是为了在简单的代码路径中提供方便,而且我认为从历史上看,它已经出现在很多教程中,这会导致混淆。
看看这是否有帮助,如果您修改了代码但仍然有问题,请回来。 Post 你修改后的代码,如果你这样做的话。
React may batch multiple setState() calls into a single update for performance.
这意味着:
handleChangeStart(date) {
// this update will not be executed directly...
this.setState({
startDate: date
});
this.daysLeft();
}
daysLeft() {
// previous setState didn't yet take effect, so we access an old startDate
let {startDate, endDate} = this.state;
console.log(startDate);
console.log(endDate);
let amount = endDate.diff(startDate, 'days');
this.setState({
days: amount
});
}
您可以通过以下方式修复它:
handleChangeStart(date) {
this.setState(prevState => {
return {
startDate: date,
days: this.daysLeft(date, prevState.endDate),
}
});
}
daysLeft(startDate, endDate) {
return endDate.diff(startDate, 'days');
}