Bra*_*ute 5 material-ui luxon react-hook-form
我正在开发一个 React 应用程序,使用 React Hook Form、Material UI 和 Luxon 进行日期解析。
我已经制作了许多可重用的表单字段,并且一切都很好,但在 DatePickers 和输出格式方面遇到了一些麻烦。
基本上,我想获取输出的 DatePicker 和 TimePicker 的值并正确格式化它以发送到后端。
我有以下组件:
日期选择器:
import React from "react";
import PropTypes from "prop-types";
import {Controller, useFormContext} from "react-hook-form";
import DatePicker from '@mui/lab/DatePicker';
import DateAdapter from '@mui/lab/AdapterLuxon';
import LocalizationProvider from '@mui/lab/LocalizationProvider';
import TextInput from "../TextInput/TextInput";
export const DATE_INPUT_FORMAT = "MM/dd/yyyy";
export const DateInput = ({name, label, defaultValue, ...props}) => {
const {control, register, formState: {errors}} = useFormContext();
return (
<Controller
name={name}
control={control}
render={({field}) => (
<LocalizationProvider dateAdapter={DateAdapter}>
<DatePicker
{...field}
inputFormat={DATE_INPUT_FORMAT}
renderInput={(props) => (
<TextInput
label={label}
defaultValue={defaultValue}
{...register(name)}
error={!!errors[name]}
helperText={errors[name] ? errors[name]?.message : ''}
{...props}
/>
)}
{...props}
/>
</LocalizationProvider>
)}
/>
)
};
DateInput.propTypes = {
name: PropTypes.string.isRequired,
label: PropTypes.string,
defaultValue: PropTypes.string
};
DateInput.defaultProps = {
label: "",
defaultValue: "",
};
export default DateInput;
Run Code Online (Sandbox Code Playgroud)
和时间选择器:
import React from "react";
import PropTypes from "prop-types";
import {Controller, useFormContext} from "react-hook-form";
import TimePicker from '@mui/lab/TimePicker';
import DateAdapter from '@mui/lab/AdapterLuxon';
import LocalizationProvider from '@mui/lab/LocalizationProvider';
import TextInput from "../TextInput/TextInput";
export const TIME_INPUT_FORMAT = "hh:mm a";
export const TimeInput = ({name, label, defaultValue, ...props}) => {
const {control, register, formState: {errors}} = useFormContext();
return (
<Controller
name={name}
control={control}
render={({field}) => (
<LocalizationProvider dateAdapter={DateAdapter}>
<TimePicker
{...field}
inputFormat={TIME_INPUT_FORMAT}
renderInput={(props) => (
<TextInput
label={label}
defaultValue={defaultValue}
{...register(name)}
error={!!errors[name]}
helperText={errors[name] ? errors[name]?.message : ''}
{...props}
/>
)}
{...props}
/>
</LocalizationProvider>
)}
/>
)
};
TimeInput.propTypes = {
name: PropTypes.string.isRequired,
label: PropTypes.string,
defaultValue: PropTypes.string
};
TimeInput.defaultProps = {
label: "",
defaultValue: "",
};
export default TimeInput;
Run Code Online (Sandbox Code Playgroud)
两者都使用 Luxon 作为 dateAdpater。该表单运行良好,并且值更新良好。但是,在处理 onSubmit 时,我正在读取表单值并将它们发送回后端,并且我的 DatePicker 和 TimePicker 以以下格式返回它们的值:
日期:“2021 年 11 月 13 日星期六 23:36:59 GMT-0500(东部标准时间)”
时间:“2021-11-02T18:30:03.317-04:00”
其中日期正确设置为日期,时间正确设置为时间。我假设读取 UI 上的值所产生的值将以 Luxon 日期格式返回,或者至少可以轻松解析为 Luxon 日期格式。这样我就可以将它们组合并格式化为日期时间字符串,以便数据库能够接受它们。
我知道我可以手动解析日期字符串,但我认为必须有更好的方法来做到这一点。然而,我已经在 Luxon 和 MUI 文档中搜索了几个小时,但没有任何运气。
任何对此的帮助将不胜感激。
举个例子:
我采用两个表单值并将它们传递到一个函数中,例如:
export const formatDateAndTimeToDatetimeField = (date, time) => {
const dateParsed = {Something here};
const timeParsed = {Something here};
const datetime = Datetime.fromObject({
year: dateParsed.year,
month: dateParsed.month,
day: dateParsed.day,
hour: timeParsed.hour,
minute: timeParsed.minute,
});
return datetime.toUTC().toFormat("yyyy-MM-dd hh:mm:ss+00:00");
}
Run Code Online (Sandbox Code Playgroud)
如果不编写代码来显式解析字符串,我就无法完全弄清楚{Something here}。我认为 Luxon 一定有一个更强大/更简单的解决方案,但我在任何地方都找不到它
感谢您提前提供的任何帮助。
小智 0
你好,是的,有一个更好的方法来解析字符串,我也对 MUI 如何处理 DateTime 输入感到困惑。
事实上,一旦您date在表单中获取了 as 字符串,然后将其提交到后端,您就可以使用 luxon 解析该字符串以获取完整的 DateTime 对象并应用您想要的所有格式。
import {DateTime} from 'luxon';
const Submit = (data) => {
const date = DateTime.fromISO(data.date);
// now you can use date object like a normal luxon DT object
const payload = date.toSQLDate()
// here request your backend with the payload
}
Run Code Online (Sandbox Code Playgroud)
我的 DatePicker 组件如下所示:
import React from 'react';
import { useController } from 'react-hook-form';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { DatePicker as MuiDatePicker } from '@mui/x-date-pickers/DatePicker';
import MuiTextField from '@mui/material/TextField';
import { AdapterLuxon } from '@mui/x-date-pickers/AdapterLuxon';
const DatePicker = ({ label, control, name, renderInput, inputFormat }) => {
const {
field: { onChange, value },
} = useController({ control, name, defaultValue: '' });
const changeHandler = (value) => {
onChange(value.toISO());
};
const renderInputDefault = (props) => <MuiTextField {...props} />;
return (
<LocalizationProvider dateAdapter={AdapterLuxon}>
<MuiDatePicker
value={value}
onChange={changeHandler}
renderInput={renderInput ? renderInput : renderInputDefault}
label={label}
disableMaskedInput
inputFormat={inputFormat}
/>
</LocalizationProvider>
);
};
Run Code Online (Sandbox Code Playgroud)
希望它会有所帮助:)
| 归档时间: |
|
| 查看次数: |
3119 次 |
| 最近记录: |