React Material-ui Datepicker / Timepicker OnChange Event 回调函



我对 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 种方法合并为一种方法。dateChangedstartChangedendChanged所有这些方法都插入到material-UI的Datepicker/TimepickeronChange道具中。通常我会做这样的事情

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

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

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

请参阅此处的源代码,请查看第 149 行。

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

有什么解决方案可以防止我为这种类似的操作使用 3 个不同的接触点?

附言对不起...传播滥用:)

状态更新合并

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

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

请参阅:状态更新已合并

主处理器

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

您只需要categorydate(不需要事件(:

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代替startChangedendChangeddateChanged

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

我还无法发表评论。所以这里是:

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

最新更新