React JS - onChange函数被触发两次

5
我在使用React时遇到了日期输入的问题。日期值来自于GraphQL,格式为dd.mm.yyyy,但是为了设置HTML日期输入的默认值,我将其转换为yyyy.mm.dd,并且为了再次保存数据,我需要反过来进行转换。
我正在将日期保存在状态中,并调用onChange函数来更新值并转换格式。
问题在于此函数会被触发两次onChange,并返回NaN-NaN-NaN(第二次运行时),但并非每次都出现,有时候正常(奇怪)。对于某些日期,它可以正常工作,例如02.03.2000没有错误,只执行一次。
对于24,它被调用了两次,并在第二次调用时出现错误(见截图)。也许转换方式有误?如果我从输入中删除defaultValue,则它只被调用一次。

enter image description here

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")}
/>

ConvertDate是什么?一个功能组件吗?它没有return方法。 - vsync
它返回给定格式的日期。 - Musawar
那么你的 render 函数在哪里?这段代码中间的 <input 元素是什么,没有任何上下文说明? - vsync
为什么您的输入没有传递value属性?defaultValue属性仅用于初始渲染。请使用"value"属性而不是"defaultValue"属性,看看是否解决了您的问题。 - Hussain Nawaz Lalee
1个回答

6
函数被调用了两次,因为你在render方法中调用了两次。
  1. 第一次调用: 输入:onChange() 调用 ConvertDate() 方法并设置状态。当设置状态时,组件重新渲染。
  2. 第二次调用:组件重新渲染,并在获取 defaultValue 时调用 ConvertDate() 方法。
我建议将 defaultValue 存储在状态中,并从状态中检索该值,而不是在 render 方法中调用函数。
你收到 NaN-NaN-NaN 是因为无效的日期被传递给你的函数“ConvertDate”。原因可能是你从 API 中接收到的日期在某些方面是不正确的。尝试使用 momentjs 进行日期处理和转换,它相对简单,可以避免错误。 编辑:
Javascript Date() 构造函数接受这两种格式 "yyyy-mm-dd" 或 "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

更新:
MomentJS 不再是推荐的日期操作库,因为它已经过时了,现在有更好、更小的替代品可用。不推荐使用

1
onChange函数被调用两次,如果我从输入中删除defaultValue,则不会出现这种情况。我认为在设置defaultValue时也会触发onChange事件。但是为什么只有某些日期存在问题呢? - Musawar
JavaScript Date() 构造函数期望的日期格式为 mm.dd.yyyy 或 yyyy.mm.dd。问题在于,对于前两个字符的值大于“12”的日期,因为只有 12 个月,所以会出现问题。 - Hussain Nawaz Lalee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接