AZSWQ
AZSWQ

Reputation: 319

React - input date field not updating value in state

I am creating a date picker field in my React App.

import React, { Component } from 'react'
...

DateInput.propTypes = {
  type: oneOf(['date']),
  placeholder: string.isRequired,
  maxLength: string,
  disabled: bool,
}

export default DateInput

I tried this.change like other fields but that does not work either.

How to get the new value updated in the state ?

Upvotes: 1

Views: 3151

Answers (1)

remix23
remix23

Reputation: 3019

If you want the DateInput to reflect the state of it's parent component (this.state.age), then you have to somehow make the DateInput display this age.

This is done by the use of props.

Since DateInput is a wrapper around a plain input element you should use the value and onChange (not change) props:

render() {
    let {
        ...
        ...
        age,
        ...
     } = this.state
     ...
     ...
     //date of birth
     let stringAge = age.toString()
     stringAge = stringAge.substring(0, 4) + '-' +
     stringAge.substring(4, 6) + '-' +
     stringAge.substring(6, 8)
     ...
         <DateInput
             type="date"
             value={age}
             onChange={this.changeDOB}
             placeholder={stringAge}
             className="datePicker"
          />
}

This is what one could call a "controlled" input. Whenever possible, a React component should be made "pure" that is a pure function of its props.

Also the changeDOB handler should be bounded to the component instance otherwise this won't be what you expect and the this.setState(...) call will fail.

This can be done either in the contructor (boring but better*):

contructor(props) {
    super(props);
    this.changeDOB = changeDOB.bind(this);
}

or when defining the method (convenient but with caveats**):

changeDOB = () => {
    this.setState({ age: document.getElementByClassNames("datePicker").value })
}

or when attaching the handler to the prop (discouraged***):

<DateInput
     type="date"
     value={age}
     onChange={() => this.changeDOB()}
     placeholder={stringAge}
     className="datePicker"
 />

Here the DateInput is a controlled component (as in controlled by its props and therefore by its parent), both in display (age) and behavior (onChange).

The parent component becomes the child component's controller. This way of thinking is everywhere in React.

(* it's the most standard and performant way of doing it)

(** some IDE are not fond of this when it comes to intellisense)

(*** it's a performance issue because it generates new instances for a value of a prop during each render)

Upvotes: 3

Related Questions