How to get a value from DateTime picker in React?

Viewed 1396

I use Material-UI in order to create a DateTime picker. Here is my demo code.

I added console.log to the function handleChange in order to see a current selected value. However, the value does not change when I use DatTime picker:

handleChange = name => event => {
  const target = event.target;
  const name = target.name;
  console.log("plannedDep", this.state.plannedDep)
  this.setState({
      [name]: event.target.value
  });
};
3 Answers
  1. I added the state value as default value to plannedDep. value={this.state.plannedDep}

  2. I changed the onChange this way: onChange={(event) => this.handleChange("plannedDep", event)}. Going by your code, onChange={this.handleChange("plannedDep")} the onchange you have will be fired as soon as the component is mounted and for every state/prop change resulting in unnecessary renders.

<TextField
  id="datetime-local"
  label="Next appointment"
  type="datetime-local"
  onChange={(event) => this.handleChange("plannedDep", event)}
  value={this.state.plannedDep}
  className={classes.textField}
  InputLabelProps={{
    shrink: true,
  }}
 />
  1. We have to check the value after setting the state, not before setting it. Im doing the check in the setState's callback, and it shows the updated value to me.
handleChange = (name, event) => {
  const target = event.target; // Do we need this?(unused in the function scope)!
  this.setState({
    [name]: event.target.value
  }, () => {
    console.log(this.state.plannedDep)
    // Prints the new value.
  });
};

I hope this solves your problem :)

You override the name argument passed to the method handleChange inside that method, doing const name = target.name;, so when you set back the state at the end:

this.setState({
  [name]: event.target.value
})

You are not setting the expected plannedDep.

You can fix it in two ways:

1) Set the state directly through:

this.setState({
  plannedDep: event.target.value
})

2) Add a name attribute to your TextField so that target.name will be the value of the name attribute of your TextField which fired the event:

<TextField
  id="datetime-local"
  name="plannedDep" // see here!
  label="Next appointment"
  type="datetime-local"
  onChange={this.handleChange("plannedDep")}
  defaultValue="2017-05-24T10:30"
  className={classes.textField}
  InputLabelProps={{
    shrink: true
  }}
/>

Here the working demo

I believe the issue is your onChange handler. If you are passing a value into the onChange you must initialize it in a callback. Try changing your onChange to onChange={() => this.handleChange("plannedDep")}

Related