admin管理员组

文章数量:1316540

I got an issue while working with date input in react. so the date value is ing from graphQL and format of date is dd.mm.yyyy but in order to set a default value for HTML date input I am converting format to yyyy.mm.dd and for saving data again I need to do vice versa.

I am saving date in state and calling on change function to update values and converting formats.

the problem is that this function is being triggered twice onChange and returning NaN-NaN-NaN (on 2nd run) but not each time only sometimes (weird). And, with some dates, it works fine, for example, with 02.03.2000 no error and executed only once.

with 24 it called twice and error on 2nd call (see screenshot). maybe conversion is wrong somehow? and if I remove defaultValue from input then it called only once.

state = {
    newUser: {
      geburtsdatum: "01.02.2000"
    }
}

ConvertDate(htmlDate, format) {
    var date = new Date(htmlDate);
    var dd = date.getDate();
    var mm = date.getMonth() + 1;
    var yyyy = date.getFullYear();
    if (dd < 10) {
      dd = "0" + dd;
    }
    if (mm < 10) {
      mm = "0" + mm;
    }
    if (format === "graphql") date = dd + "." + mm + "." + yyyy;
    if (format === "html") date = yyyy + "-" + dd + "-" + mm;
    return date;
}

onChange = e => {
    let value = e.target.value;
    let name = e.target.name;
    if (e.target.type === "date") {
      value = this.convertDate(value, "graphql");
    console.log(value, name);
    }
    this.setState(prevState => {
      return {
        newUser: {
          ...prevState.newUser,
          [name]: value
        }
      };
    });
  };

<input
    type="date"
    name="geburtsdatum"
    defaultValue={this.convertDate(this.state.newUser.geburtsdatum, "html")}
    onChange={this.onChange}
    placeholder={this.getDJHTooltip("geburtsdatum")}
/>

I got an issue while working with date input in react. so the date value is ing from graphQL and format of date is dd.mm.yyyy but in order to set a default value for HTML date input I am converting format to yyyy.mm.dd and for saving data again I need to do vice versa.

I am saving date in state and calling on change function to update values and converting formats.

the problem is that this function is being triggered twice onChange and returning NaN-NaN-NaN (on 2nd run) but not each time only sometimes (weird). And, with some dates, it works fine, for example, with 02.03.2000 no error and executed only once.

with 24 it called twice and error on 2nd call (see screenshot). maybe conversion is wrong somehow? and if I remove defaultValue from input then it called only once.

state = {
    newUser: {
      geburtsdatum: "01.02.2000"
    }
}

ConvertDate(htmlDate, format) {
    var date = new Date(htmlDate);
    var dd = date.getDate();
    var mm = date.getMonth() + 1;
    var yyyy = date.getFullYear();
    if (dd < 10) {
      dd = "0" + dd;
    }
    if (mm < 10) {
      mm = "0" + mm;
    }
    if (format === "graphql") date = dd + "." + mm + "." + yyyy;
    if (format === "html") date = yyyy + "-" + dd + "-" + mm;
    return date;
}

onChange = e => {
    let value = e.target.value;
    let name = e.target.name;
    if (e.target.type === "date") {
      value = this.convertDate(value, "graphql");
    console.log(value, name);
    }
    this.setState(prevState => {
      return {
        newUser: {
          ...prevState.newUser,
          [name]: value
        }
      };
    });
  };

<input
    type="date"
    name="geburtsdatum"
    defaultValue={this.convertDate(this.state.newUser.geburtsdatum, "html")}
    onChange={this.onChange}
    placeholder={this.getDJHTooltip("geburtsdatum")}
/>
Share Improve this question edited Oct 19, 2019 at 17:31 vsync 131k59 gold badges340 silver badges422 bronze badges asked Oct 19, 2019 at 15:50 MusawarMusawar 1031 gold badge3 silver badges10 bronze badges 4
  • What is ConvertDate? A functional ponent? there is no return method – vsync Commented Oct 19, 2019 at 16:52
  • it returns date with given format. – Musawar Commented Oct 19, 2019 at 17:05
  • So where is your render function? what is this <input element in the middle of the code, without any context? – vsync Commented Oct 19, 2019 at 17:31
  • Why doesn't your input have a value prop passed to it? defaultValue prop is only for the initial render. Use the "value" prop instead of "defaultValue" and see if your problem is fixed. – Hussain Nawaz Lalee Commented Oct 19, 2019 at 18:34
Add a ment  | 

1 Answer 1

Reset to default 6

The function is called twice because you are calling it twice in your render method.

  1. 1st Call: On input: onChange() calls the ConvertDate() method and sets state. On setting state ponent re-renders
  2. 2nd Call: Component re-renders and the ConvertDate() method is called when getting defaultValue

I would remend storing the defaultValue in state and retrieving that value from state instead of calling a function in the render method.

You receive NaN-NaN-NaN because an invalid date is being passed to your function "ConvertDate". The reason might be that the date you receive from API is incorrect in some way. Try using momentjs for date handling and conversion, its relatively simple and you can avoid bugs

Edit:
Javascript Date() constructor accepts these two formats "yyyy-mm-dd" or "mm-dd-yyyy".

console.log(new Date("2019-12-14")); // valid yyyy-mm-dd
console.log(new Date("2019-14-12")); // invalid yyyy-dd-mm

console.log(new Date("12-14-2019")); // valid mm-dd-yyyy
console.log(new Date("14-12-2019")); // invalid dd-mm-yyyy

Update:
MomentJS is not the remended library for manipulating dates anymore, as it is outdated and there are much better and smaller alternatives available.

本文标签: javascriptReact JSonChange function is being triggered twiceStack Overflow