簡體   English   中英

MUI 時間選擇器不在輸入字段中顯示格式化的時間值

[英]MUI Time picker doesn't show formatted time value in input field

我的主要目標是使用帶有 yup 驗證和 react-hook-form 的 MUI 時間選擇器,但我面臨的問題是,當我從時間選擇器中選擇時間時,文本字段中的值不會更新,如下所示。 主要問題圖片

我為我的數據庫使用了“TIME”類型,所以我需要對輸入進行格式化。 但是,工作時間(結束時間)返回數據庫中不接受的帶有日期的時間。 差異顯示在下面的控制台日志中。

day: "tuesday"
end_time: "Tue May 31 2022 05:27:00 GMT+0545 (Nepal Time)"
start_time: "05:29:00"
subject: "Account"
[[Prototype]]: Object

這是我的源代碼:

import React, { useState, useEffect } from 'react'
import { Button, Box, Card, CardContent, TextField, Typography, CardHeader, Grid, MenuItem } from '@mui/material';
import { useNavigate, useParams } from 'react-router-dom';
import { useForm, Controller } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import * as Yup from 'yup';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { TimePicker, LocalizationProvider } from '@mui/x-date-pickers';
import { format, parseISO } from 'date-fns';
import TimeTableService from '../../../services/timetable.service';
import SubjectService from '../../../services/subject.service';

const TimetableForm = () => {
    const { id } = useParams();
    const validationSchema = Yup.object().shape({
        day: Yup.string().required("Day is required"),
        start_time: Yup.string().required("Start time is required"),
        end_time: Yup.string().required("End time is required"),
        subject: Yup.string().required("Subject is required"),
    });
    const {
        control,
        handleSubmit,
        setValue,
        formState: { errors }
    } = useForm({ resolver: yupResolver(validationSchema), mode: 'onChange' });
    const initialTimeTableState = {
        id: null,
        day: '',
        start_time: '',
        end_time: '',
        Subject: {},
    }
    const [currentTimeTable, setCurrentTimeTable] = useState(initialTimeTableState);
    const [subjects, setSubjects] = useState([]);
    const [editMode, setEditMode] = useState(false);
    const [loading, setLoading] = useState(false);
    const [message, setMessage] = useState("");
    const navigate = useNavigate();

    useEffect(() => {
        SubjectService.getAllSubjects().then(response => {
            setSubjects(response.data);
        })
        if (id) {
            TimeTableService.getTimeTable(id).then(response => {
                const timeTable = response.data;
                const fields = ['day', 'start_time', 'end_time'];
                fields.forEach(field => setValue(field, timeTable[field]));
                setValue('subject', timeTable.Subject.name);
                setCurrentTimeTable(timeTable);
                setEditMode(true);
            })
        }
    }, [id, setValue]);

    const onError = (errors, e) => console.log(errors, e);
    const onSubmit = (data) => {
        const start_time = data.start_time;
        // const start = format(start_time, "hh:mm a");
        console.log(start_time, data);
        // setMessage("");
        // setLoading(true);
        // if (editMode) {
        //     TimeTableService.updateTimeTable(id, data).then(() => {
        //         setLoading(false);
        //         navigate("/dashboard/timetable");
        //     }, (error) => {
        //         const resMessage = (error.response && error.response.data && error.response.data.message) || error.message || error.toString();
        //         setLoading(false);
        //         setMessage(resMessage);
        //     });
        // } else {
        //     TimeTableService.createTimeTable(data).then(() => {
        //         setLoading(false);
        //         navigate("/dashboard/timetable");
        //         window.location.reload();
        //     }, (error) => {
        //         const resMessage = (error.response && error.response.data && error.response.data.message) || error.message || error.toString();
        //         setLoading(false);
        //         setMessage(resMessage);
        //     });
        // }
    }

    const days = [
        {
            title: "Sunday",
            value: "sunday"
        },
        {
            title: "Monday",
            value: "monday"
        },
        {
            title: "Tuesday",
            value: "tuesday"
        },
        {
            title: "Wednesday",
            value: "wednesday"
        },
        {
            title: "Thursday",
            value: "thursday"
        },
        {
            title: "Friday",
            value: "friday"
        },
        {
            title: "Saturday",
            value: "saturday"
        }
    ];

    return (
        <Box sx={{ mt: 3 }}>
            <Card>
                <Box sx={{ minWidth: 1050 }}>
                    <CardHeader
                        title={id ? "Edit Time Table" : "Add Time Table"}
                    />
                    <CardContent>
                        {message && (<Typography variant='body2' color='error' >{message}</Typography>)}
                        <Grid container spacing={2}>
                            <Grid item md={4} xs={6}>
                                <LocalizationProvider dateAdapter={AdapterDateFns}>
                                    <Controller
                                        control={control}
                                        name="start_time"
                                        defaultValue={currentTimeTable.start_time || ""}
                                        render={({ field }) => (
                                            <TimePicker
                                                {...field}
                                                inputFormat="HH:mm:ss"
                                                mask='__:__:__'
                                                label="Start Time"
                                                onChange={(time) => {
                                                    const formattedTime = format(time, "HH:mm:ss");
                                                    field.onChange(formattedTime);
                                                }}
                                                renderInput={(params) => (
                                                    <TextField
                                                        {...params}
                                                        fullWidth
                                                        label="Start Time"
                                                        variant="outlined"
                                                        margin='dense'
                                                        color='dark'
                                                        size='small'
                                                        error={errors.start_time ? true : false}
                                                    />
                                                )}
                                            />
                                        )}
                                    />
                                </LocalizationProvider>
                                <Typography variant="body2" color="error">
                                    {errors.start_time?.message}
                                </Typography>
                            </Grid>
                            <Grid item md={4} xs={6}>
                                <LocalizationProvider dateAdapter={AdapterDateFns}>
                                    <Controller
                                        control={control}
                                        name="end_time"
                                        defaultValue={currentTimeTable.end_time || ""}
                                        render={({ field }) => (
                                            <TimePicker
                                                {...field}
                                                label="End Time"
                                                // onChange={(time) => field.onChange(time)}
                                                renderInput={(params) => (
                                                    <TextField
                                                        {...params}
                                                        fullWidth
                                                        label="End Time"
                                                        variant="outlined"
                                                        margin='dense'
                                                        color='dark'
                                                        size='small'
                                                        error={errors.end_time ? true : false}
                                                    />
                                                )}
                                            />
                                        )}
                                    />
                                </LocalizationProvider>
                                <Typography variant="body2" color="error">
                                    {errors.end_time?.message}
                                </Typography>
                            </Grid>
                            <Grid item md={4} xs={6}>
                                <Controller
                                    control={control}
                                    name='subject'
                                    defaultValue={currentTimeTable.Subject.name || ""}
                                    render={({ field }) => (
                                        <>
                                            <TextField
                                                {...field}
                                                select
                                                fullWidth
                                                label='Subject'
                                                variant='outlined'
                                                margin='dense'
                                                color='dark'
                                                size='small'
                                                error={errors.subject ? true : false}
                                            >
                                                {subjects.map(subject => (
                                                    <MenuItem key={subject.id} value={subject.name}>{subject.name}</MenuItem>
                                                ))}
                                            </TextField>
                                        </>
                                    )}
                                />
                                <Typography variant="body2" color="error">
                                    {errors.subject?.message}
                                </Typography>
                            </Grid>
                            <Grid item md={4} xs={6}>
                                <Controller
                                    control={control}
                                    name='day'
                                    defaultValue={currentTimeTable.day || ""}
                                    render={({ field }) => (
                                        <>
                                            <TextField
                                                {...field}
                                                select
                                                fullWidth
                                                label='Day'
                                                variant='outlined'
                                                margin='dense'
                                                color='dark'
                                                size='small'
                                                error={errors.day ? true : false}
                                            >
                                                {days.map(day => (
                                                    <MenuItem key={day.title} value={day.value}>{day.title}</MenuItem>
                                                ))}
                                            </TextField>
                                        </>
                                    )}
                                />
                                <Typography variant="body2" color="error">
                                    {errors.day?.message}
                                </Typography>
                            </Grid>
                        </Grid>
                        <Button
                            variant='outlined'
                            color={(loading) ? 'warning' : 'success'}
                            sx={{ my: 1.5 }}
                            disabled={(loading) ? true : false}
                            onClick={handleSubmit(onSubmit, onError)}>
                            {(loading) ? "Loading..." : "Submit"}
                        </Button>
                    </CardContent>
                </Box>
            </Card>
        </Box>
    )
}

export default TimetableForm

有沒有什么辦法解決這一問題? 謝謝。

注意: TimetableForm組件是使用 react 路由的<Outlet />渲染的。

編輯:這是 codeSandbox 鏈接: https ://codesandbox.io/s/gifted-roentgen-94bnpq

問題出在這行代碼中:

onChange={(time) => {
          const formattedTime = format(time, "HH:mm:ss");
          field.onChange(formattedTime);
}}

這是因為format(time, "HH:mm:ss")返回一個String ,但時間選擇器需要一個Date對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM