人们在React中如何处理HTML原生日期输入?

huangapple go评论62阅读模式
英文:

How are people handling HTML-native Date inputs in React?

问题

We've got a <input type="date" /> in our app and I'm struggling to make it work as you would expect.

I've put an example here: https://codesandbox.io/s/romantic-microservice-pg62sq, but the general issue is that if you enter the date using the keyboard (e.g. 01012023 for the 1st of January 2023), it considers it an incomplete date for the 0101 but as soon as you type 2 it sets it to the 1st of January 0002, which due to timezone/calendar reasons gets rendered as Mon Dec 31 0001 23:58:45 GMT-0001 (Greenwich Mean Time) and fills in the control to read 31/12/0001.

At this point you can't recover without having to use the mouse which feels less than ideal.

I know we can avoid this by using defaultValue instead of value, but we've got other things which can update this field, and want to avoid using refs if at all possible.

英文:

We've got a &lt;input type=&quot;date&quot; /&gt; in our app and I'm struggling to make it work as you would expect.

I've put an example here: https://codesandbox.io/s/romantic-microservice-pg62sq, but the general issue is that if you enter the date using the keyboard (e.g. 01012023 for the 1st of January 2023), it considers it an incomplete date for the 0101 but as soon as you type 2 it sets it to the 1st of January 0002, which due to timezone/calendar reasons gets rendered as Mon Dec 31 0001 23:58:45 GMT-0001 (Greenwich Mean Time) and fills in the control to read 31/12/0001.

At this point you can't recover without having to use the mouse which feels less than ideal.

I know we can avoid this by using defaultValue instead of value, but we've got other things which can update this field, and want to avoid using refs if at all possible

答案1

得分: 1

不要将输入值转换并传递回输入元素。正如您所看到的,这样做很脆弱,可能在重新渲染组件时导致意外行为。

除非您尝试进行自己的解析和输入格式化,否则在React中存储的状态和传递到输入元素中的值应始终与从事件目标检索到的.value相同。(还要注意,初始值也应匹配并始终为空字符串)。

相反,如果您需要以某种方式转换value,可以使用派生状态(以及可能的useMemo),如下所示:

英文:

Don't transform the input value and pass it back into the input element. As you can see, it's fragile and can lead to unexpected behavior when rerendering the component.

Unless you are trying to do your own parsing and input formatting, the value stored in state and passed into an input element in React should always be the same as the .value retrieved from the event target. (Also note that the initial value should match as well and always be an empty string).

Instead, if you need to transform value somehow, use derived state (and potentially useMemo), like so:

function getValueForDateInput(value: string): string {
  return !value ? &quot;&quot; : format(new Date(value), &quot;yyyy-MM-dd&quot;);
}

export default function App() {

  const [value, setValue] = useState&lt;string&gt;(&quot;&quot;);
  
  const derivedValue = useMemo(() =&gt; getValueForDateInput(value), [value]);
  console.log(derivedValue)

  return (
    &lt;input
      autoFocus
      type=&quot;date&quot;
      pattern=&quot;####-##-##&quot;
      value={value}
      onInput={(e) =&gt; setValue(e.target.value)}
    /&gt;
  );
}

huangapple
  • 本文由 发表于 2023年6月13日 16:44:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76463149.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定