【问题标题】:React Material-ui Datepicker / Timepicker OnChange Event callback function encapsulationReact Material-ui Datepicker / Timepicker OnChange 事件回调函数封装
【发布时间】:2018-01-06 08:45:17
【问题描述】:

我对 React 还很陌生,我正在使用 Material-ui 作为额外的 UI 依赖项。我的代码中有一些重复,删除起来有点棘手,因为我认为我受到 Material-ui 组件实现的限制。

这是我需要帮助重新组织的课程

...other imports...
import EntryForm from './entryform';
export default class TimeSheet extends Component {

constructor(props) {
    ...
    this.state = {
        entry: {
            date: null,
            startTime: null,
            endTime: null,
        },
        list: []
    };

    // ... Class method bindings here ...
}


// ------- METHODS I WOULD LIKE TO CONSOLIDATE -----
dateChanged(event, date) {
    this.setState(prevState => ({
        ...prevState,
        entry: { ...prevState.entry, date: new Date(date) }
    }));
}

startChanged(event, date) {
    this.setState(prevState => ({
        ...prevState,
        entry: { ...prevState.entry, startTime: new Date(date) }
    }));
}

endChanged(event, date) {
    this.setState(prevState => ({
        ...prevState,
        entry: { ...prevState.entry, endTime: new Date(date) }
    }));
}
// ------- METHODS I WOULD LIKE TO CONSOLIDATE -----

saveTimeSheetEntry(event) {
    this.setState((prevState) => ({
        ...prevState,
        list: prevState.list.concat([{
            ...prevState.entry
        }])
    }));
}

render() {
    return (
       ...some stuff

            <EntryForm
                dateChanged={this.dateChanged}
                startChanged={this.startChanged}
                endChanged={this.endChanged}
                date={this.state.entry.date}
                startTime={this.state.entry.startTime}
                endTime={this.state.entry.endTime}
                save={this.saveEntry}
            />

        ...other stuff
    )
}
}

编辑

./EntryForm 组件

const EntryForm = (props) => (
    <Paper style={paperStyle} zDepth={1}>
        <DatePicker onChange={props.dateChanged} value={props.date} hintText="Timesheet Date" />
        <TimePicker onChange={props.startChanged} value={props.startTime} hintText="Start Time" />
        <TimePicker onChange={props.endChanged} value={props.endTime} hintText="End Time" />
        <FlatButton onClick={props.save} label="Save" backgroundColor="#18cbce" fullWidth={true} />
    </Paper>
);

如您所见,我想尝试将 3 种方法合并为一个方法。 dateChanged startChanged 和 endChanged 所有这些方法都插入到 material-ui 的 Datepicker/Timepicker onChange 属性中。通常我会做这样的事情

handleChange(event, date, stateItem) {
    this.setState(state => ({
        ...state,
        entry: { ...state.entry, [stateItem]: date }
    }));
}

但是当我尝试时它会抛出一个错误,可能是因为 日期/时间选择器实现如下所示。

<Timepicker onChange={props.startChange} ...otherProps />

see the source code for this here查看第 149 行。

没关系,因为该应用程序很小,而且它只是一个基本的时间表条目。但是如果我必须对许多状态对象执行此操作,它会变得非常不守规矩。

是否有任何解决方案可以阻止我使用 3 个不同的接触点来进行类似的操作?

附言抱歉......传播滥用:)

【问题讨论】:

  • But when I try it throws an error(什么错误?)
  • sorry for ...spread abuse : 你不需要设置完整状态
  • 你能解释一下什么/什么时候触发吗:startChanged和endChanged
  • 如果您可以在帖子中添加./entryform'的代码^^
  • 谢谢我更新了我的答案,你得到错误 date is undefined 因为onChange 只有一个参数 value 你正在传递第二个参数(未定义)^^

标签: javascript reactjs oop material-ui


【解决方案1】:

我还不能发表评论。所以这里是:

我认为你不能,因为你需要区分你想要设置的状态。如果您合并这些方法,您将需要一个 switch 或 if 或其他我认为更糟糕的东西。

【讨论】:

  • 是的,我也很难找到另一种方法。因此这个问题。如果有人想不出什么,我可能会在 material-ui github 上提出功能请求。
【解决方案2】:

状态更新被合并

当你调用 setState() 时,React 会将你提供的对象合并到当前状态中。

你不需要更新完整的状态,react会更新independently给定的对象,其余的将保持不变。

见:States updates are merged

主处理程序

我想尝试将 3 种方法合并为一个方法

你只需要category和date(不需要事件):

     handleChange(category, date) {
        this.setState(prevState => {

            // Get previous state
            const { entry } = prevState;

            // Set state: date | startTime | endTime
            entry[category] = date; 

            //Update state
            return { entry };
        });
     }

绑定处理程序

在内部组件中使用this 和setState:

<EntryForm onChange={ this.handleChange.bind(this) } {...} />

使用处理程序

只需使用this.props.onChange 而不是startChanged、endChanged、dateChanged:

//dateChanged
this.props.onChange('date', date);

//startChanged
this.props.onChange('startTime', date);

//endChanged
this.props.onChange('endTime', date);

时间选择器

但是当我尝试时它会抛出一个错误,可能是因为日期/时间选择器实现看起来像这样。

onChange 回调只传递一个参数value(即日期)

function onChange(value) {
  console.log(value && value.format(format));
}

由于您只需要date,您可以使用匿名函数覆盖实现
(只需将其包装在另一个函数中):

<Timepicker onChange={ date => { props.onChange('date', date ) } />

【讨论】:

  • 这是一个非常好的答案。我确实尝试过类似的东西。但它几乎没有那么干净。不幸的是,因为我必须像 &lt;TimePicker onChange={props.startChanged} value={props.startTime} hintText="Start Time" /&gt; 这样使用 Timepicker 的 onChange,所以抛出的错误是 'date' is not defined no-undef 我意识到我应该从一开始就将这一行包含在原始问题中。
  • @Edwinj 谢谢我看到了文档,所以回调应该是function(value)
  • 值是日期^^
  • 您的覆盖方法非常接近!我不得不再添加一个参数,因为由于某种原因传入的第一个参数为空。 &lt;DatePicker name="date" onChange={ (noval, date) =&gt; { props.handleChange('date', date) } }
猜你喜欢
  • 2019-06-06
  • 1970-01-01
  • 1970-01-01
  • 2021-08-27
  • 2018-04-27
  • 2016-07-05
  • 1970-01-01
  • 1970-01-01
  • 2021-02-11
相关资源
最近更新 更多