admin管理员组文章数量:1424970
I'm fairly new to React and I'm using Material-ui as an additional UI dependency. I have some repetition in my code that is a little tricky to remove since I think I'm restricted by a Material-ui ponent's implementation.
Here's my class that I need help with re-organizing
...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
)
}
}
EDIT
./EntryForm
Component
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>
);
As you can see, there are 3 methods that I would like to try to consolidate into a single method. dateChanged
startChanged
and endChanged
all of these methods are plugged into material-ui's Datepicker/Timepicker
onChange
prop. Normally I would just do something like this
handleChange(event, date, stateItem) {
this.setState(state => ({
...state,
entry: { ...state.entry, [stateItem]: date }
}));
}
But when I try it throws an error, probably because the Date/Time picker implementation looks like this.
<Timepicker onChange={props.startChange} ...otherProps />
see the source code for this here check out line 149.
It's okay because the app is small, and it's just a basic time sheet entry. But it would bee super unruly if I had to do this with many state objects.
Is there any solution that would prevent me from having 3 different touch points for such a similar operation?
p.s. sorry for ...spread abuse :)
I'm fairly new to React and I'm using Material-ui as an additional UI dependency. I have some repetition in my code that is a little tricky to remove since I think I'm restricted by a Material-ui ponent's implementation.
Here's my class that I need help with re-organizing
...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
)
}
}
EDIT
./EntryForm
Component
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>
);
As you can see, there are 3 methods that I would like to try to consolidate into a single method. dateChanged
startChanged
and endChanged
all of these methods are plugged into material-ui's Datepicker/Timepicker
onChange
prop. Normally I would just do something like this
handleChange(event, date, stateItem) {
this.setState(state => ({
...state,
entry: { ...state.entry, [stateItem]: date }
}));
}
But when I try it throws an error, probably because the Date/Time picker implementation looks like this.
<Timepicker onChange={props.startChange} ...otherProps />
see the source code for this here check out line 149.
It's okay because the app is small, and it's just a basic time sheet entry. But it would bee super unruly if I had to do this with many state objects.
Is there any solution that would prevent me from having 3 different touch points for such a similar operation?
p.s. sorry for ...spread abuse :)
Share Improve this question edited Aug 5, 2017 at 3:47 Edwinj asked Jul 30, 2017 at 21:03 EdwinjEdwinj 851 gold badge4 silver badges8 bronze badges 6-
But when I try it throws an error
( what error ? ) – btzr Commented Jul 31, 2017 at 0:20 -
sorry for ...spread abuse
: you don't need to set the full state – btzr Commented Jul 31, 2017 at 0:29 -
could you explain what / when trigger:
startChanged
andendChanged
– btzr Commented Jul 31, 2017 at 0:42 -
also if you can add the code of
./entryform'
in the post ^^ – btzr Commented Jul 31, 2017 at 1:26 -
Thanks I updated my answer, you get the error
date
is undefined becauseonChange
only have one parametervalue
you are passing the second parameter ( undefined) ^^ – btzr Commented Aug 2, 2017 at 5:27
2 Answers
Reset to default 2States updates are merged
When you call setState(), React merges the object you provide into the current state.
You don't need to update the full state, react will update independently
the given object, the rest will remain intact.
See: States updates are merged
Main handler
there are 3 methods that I would like to try to consolidate into a single method
You only need category
and date
( no need for event ):
handleChange(category, date) {
this.setState(prevState => {
// Get previous state
const { entry } = prevState;
// Set state: date | startTime | endTime
entry[category] = date;
//Update state
return { entry };
});
}
Bind handler
To make work this
and setState
inside an inner ponent:
<EntryForm onChange={ this.handleChange.bind(this) } {...} />
Using the handler
Just use this.props.onChange
instead of startChanged
, endChanged
, dateChanged
:
//dateChanged
this.props.onChange('date', date);
//startChanged
this.props.onChange('startTime', date);
//endChanged
this.props.onChange('endTime', date);
Timepicker
But when I try it throws an error, probably because the Date/Time picker implementation looks like this.
the onChange
callback only pass one argument value
(that's the date)
function onChange(value) {
console.log(value && value.format(format));
}
Since you only need date
you can override the implementation with an anonymous function
( just wrap it inside another function ):
<Timepicker onChange={ date => { props.onChange('date', date ) } />
I'm unable to ment yet. So here goes:
I don't think you can, since you need to distinguish between the states you want to set. If you consolidate these methods you would need a switch or an if or something which in my opinion is worse then this.
本文标签:
版权声明:本文标题:javascript - React Material-ui DatepickerTimepicker OnChange Event callback function encapsulation - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745418798a2657808.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论