React Material-ui Datepicker / Timepicker OnChange Event callback function encapsulation

Viewed 4613

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 component'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 become 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 :)

2 Answers
Related