You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何以编程方式更新React datetime slider picker的显示值?

问题描述

我正在使用React datetime slider picker组件,不知道如何在点击按钮等场景下以编程方式更新其值。

我通过如下方式渲染该组件:

<RDSPwidget
  enableSecond={true}
/>

其中我的RDSPwidget定义如下:

import Calendar from 'react-datetime-slider-picker/dist/Calendar';
import TimePicker from 'react-datetime-slider-picker/dist/TimePicker';
import { Tabs, Tab, Button } from '@material-ui/core';
import Language from 'react-datetime-slider-picker/public/Language';

class RDSPwidget extends React.PureComponent {
    constructor(props) {
      super(props);
  
      this.state = {
        tab: 0,
        date: {year: 2000, month: 1, date: 1},
        time: {hour: 1, minute: 1, second: 1},
        counter: 1
      };
  
      this.onTabChange = this.onTabChange.bind(this);
      this.onValueChange = this.onValueChange.bind(this);
      this.updateValue = this.updateValue.bind(this);
    }
  
    onTabChange(value) {
      this.setState({ tab: value });
    }
  
    onValueChange(isDate, value) {
      let date = this.state.date,
        time = this.state.time;
      if (isDate) {
        date = {
          year: value.year,
          month: value.month,
          date: value.date
        };
        this.setState({ date: date });
      } else {
        time = value;
        this.setState({ time: time });
      }
    }

    updateValue() {
      this.setState({ date: {year: 2020, month: 10, date: 10} });
    }
    
    componentWillReceiveProps(nextProps) {
      let that = this;
      this.setState({ date: nextProps.value.date, time: nextProps.value.time });
      let tab = this.state.tab;
      this.setState({ tab: 1-tab });
      setTimeout(function() {
        that.setState({ tab: tab });
      }, 0);
    }
  
    render() {  
  
      const language = (this.props.language === 'ko') ? Language['ko'] : Language['en'];
  
      return (
        <div className='picker'>
          <div className='picker-tab'>
            <Tabs
              value={this.state.tab}
              onChange={(event, value) => this.onTabChange(value)}
              fullWidth
              textColor='inherit'
              classes={{ indicator: 'picker-tab-indicator' }}
            >
              <Tab 
                label={language.date} 
                icon={<Today />} 
                classes={{ selected: 'selected' }} 
              />
              <Tab 
                label={language.time} 
                icon={<AccessTime />} 
                classes={{ selected: 'selected' }} 
              />
            </Tabs>
          </div>
          <div className='picker-form'>
            {(this.state.tab === 0) ?
              <Calendar
                language={this.props.language}
                defaultValue={this.state.date}
                onChange={(date) => this.onValueChange(true, date)}
              /> :
              <TimePicker
                language={this.props.language}
                enableSecond={this.props.enableSecond}
                defaultValue={this.state.time}
                onChange={(time) => this.onValueChange(false, time)}
              />}
          </div>
          <button onClick={this.updateValue}>Update</button>
        </div>
      );
    }
  }

我很久之前写的这段代码,已经忘记为什么要使用componentWillReceiveProps(nextProps)了(我对React并不熟练)。

请问如何以编程方式更改该组件显示的日期?


编辑:
问题似乎与以下条件渲染的组件有关:

<div className='picker-form'>
  {(this.state.tab === 0) ?
    <Calendar
      language={this.props.language}
      defaultValue={this.state.date}
      onChange={(date) => this.onValueChange(true, date)}
    /> :
    <TimePicker
      language={this.props.language}
      enableSecond={this.props.enableSecond}
      defaultValue={this.state.time}
      onChange={(time) => this.onValueChange(false, time)}
    />}
</div>

实际上,当我在Calendar标签页时点击按钮,没有任何反应。但如果切换到TimePicker标签页再切回Calendar标签页,更新后的日期就会显示出来。


解决方案

问题核心是你给Calendar和TimePicker组件用了defaultValue属性,这个属性仅在组件首次渲染时生效,后续状态更新不会触发组件刷新显示值。要实现编程式控制,需将组件改为受控组件,用value绑定状态而非defaultValue。

  • 替换defaultValue为value
    在条件渲染的组件中,把defaultValue替换成value,绑定对应的state值:

    <div className='picker-form'>
      {(this.state.tab === 0) ?
        <Calendar
          language={this.props.language}
          value={this.state.date}
          onChange={(date) => this.onValueChange(true, date)}
        /> :
        <TimePicker
          language={this.props.language}
          enableSecond={this.props.enableSecond}
          value={this.state.time}
          onChange={(time) => this.onValueChange(false, time)}
        />}
    </div>
    
  • 清理废弃的生命周期逻辑
    componentWillReceiveProps已经被React废弃,你之前写的切换tab逻辑是为了绕过defaultValue只初始化一次的限制。改成受控组件后,这段代码可以直接删除。如果需要从外部props接收值更新内部状态,改用componentDidUpdate:

    componentDidUpdate(prevProps) {
      if (prevProps.value !== this.props.value) {
        this.setState({ 
          date: this.props.value.date, 
          time: this.props.value.time 
        });
      }
    }
    
  • 验证效果
    修改后点击Update按钮,updateValue更新date状态,Calendar组件会因value属性变化自动刷新,直接显示新日期,无需切换tab。

内容的提问来源于stack exchange,提问作者Stéphane Laurent

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 15:15:10