页面功能如下图所示:
一共三处日期,每改动一处日期的时候,其他两处跟着改变。在点击左右箭头时,发现设置 DatePicker的value无效,一直还是上一个日期值,左右箭头的html代码及事件处理如下:
// react
<>
<div>
<CaretLeftOutlined onClick={() => this.clickTime(time.add(-1, 'days').format('YYYY-MM-DD'))} />
{timeStr}
<CaretRightOutlined onClick={() => this.clickTime(time.add(1, 'days').format('YYYY-MM-DD'))} />
</div>
<div>
<span>查看</span>
<DatePicker onChange={this.onChange} value={time} />
</div>
</>
// js部分
clickTime = (date) => {
this.setState({
time: date,
timeStr: date.format('YYYY年MM月DD日'),
})
// todo
if (this.props.time) {
this.props.setTime(date)
}
}
原本考虑onClick时直接使用moment对象的时间传入,然后this.setState设置time值,即可直接实现DatePicker的值改变,结果发现不生效。
原因分析:
antd v4版本的DatePicker不能完全通过修改value的方式改变值,日期不会被更新,最好传入一个新的moment对象。
测试:
将this.setState设置time值为moment(),可以生效。
解决办法:
将onClick事件传参中的moment对象改成字符串,即moment对象后面加上format:
onClick={() => this.clickTime(time.add(-1, 'days').format('YYYY-MM-DD'))}
在this.setState设置time值时再做处理,将字符串转换成moment对象。
完整的代码如下:
index.jsx:
import React from 'react';
import { Col, Row } from 'antd';
import Left from './left';
import Right from './right';
import moment from 'moment';
class MyComponent extends React.Component {
state = { time: moment() }
setTime = (date) => {
this.setState({ time: date });
}
render() {
const { time } = this.state;
return (
<Row gutter={16}>
<Col className="gutter-row" span={12}>
<Left time={time} setTime={this.setTime} />
</Col>
<Col className="gutter-row" span={12}>
<Right time={time} setTime={this.setTime} />
</Col>
</Row>
);
}
}
export default MyComponent;
left.jsx:
import React from 'react';
import { DatePicker } from 'antd';
import {
CaretLeftOutlined, CaretRightOutlined
} from '@ant-design/icons';
import moment from 'moment';
class Left extends React.Component {
state = {
time: this.props?.time || moment().subtract(1, 'days'),
timeStr: this.props?.time?.format('YYYY年MM月DD日') || moment().subtract(1, 'days').format('YYYY年MM月DD日'),
}
componentWillReceiveProps(prevProps, prevState) {
if (this.props.time !== prevProps.time) {
this.setState({
time: prevProps.time,
timeStr: prevProps.time.format('YYYY年MM月DD日'),
})
if (this.props.time) {
this.props.setTime(prevProps.time)
}
}
}
onChange = (date, dateString) => {
this.setState({
time: date,
timeStr: date.format('YYYY年MM月DD日'),
})
// todo
if (this.props.time) {
this.props.setTime(date)
}
};
clickTime = (date) => {
this.setState({
time: moment(date),
// time: moment(),
timeStr: moment(date).format('YYYY年MM月DD日'),
})
// todo
if (this.props.time) {
this.props.setTime(moment(date))
}
}
render() {
const { time, timeStr } = this.state;
return (
<>
<div>
<CaretLeftOutlined onClick={() => this.clickTime(time.add(-1, 'days').format('YYYY-MM-DD'))} />
{timeStr}
<CaretRightOutlined onClick={() => this.clickTime(time.add(1, 'days').format('YYYY-MM-DD'))} />
</div>
<div>
<span>查看</span>
<DatePicker onChange={this.onChange} value={time} />
</div>
</>
);
}
}
export default Left;
right.jsx:
import React from 'react';
import { DatePicker } from 'antd';
class Right extends React.Component {
state = {
time: '',
}
onChange = (date, dateString) => {
this.setState({
time: date,
timeStr: date.format('YYYY年MM月DD日'),
})
// todo
if (this.props.time) {
this.props.setTime(date)
}
};
componentWillReceiveProps(prevProps, prevState) {
if (this.props.time !== prevProps.time) {
this.setState({
time: prevProps.time,
timeStr: prevProps.time.format('YYYY年MM月DD日'),
})
if (this.props.time) {
this.props.setTime(prevProps.time)
}
}
}
render() {
const { time } = this.state;
return (
<DatePicker onChange={this.onChange} value={time} />
);
}
}
export default Right;