英文:
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 <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
答案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 ? "" : format(new Date(value), "yyyy-MM-dd");
}
export default function App() {
const [value, setValue] = useState<string>("");
const derivedValue = useMemo(() => getValueForDateInput(value), [value]);
console.log(derivedValue)
return (
<input
autoFocus
type="date"
pattern="####-##-##"
value={value}
onInput={(e) => setValue(e.target.value)}
/>
);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论