#javascript #reactjs #typescript #material-ui
Вопрос:
Я пытаюсь создать форму редактирования для редактирования данных из базы данных по идентификатору. Я попробовал это:
import React, {FormEvent, useEffect, useState} from "react"; import TextField from "@material-ui/core/TextField"; import { createStyles, makeStyles, Theme } from "@material-ui/core/styles"; import { TicketFullDTO, TicketStatusTypesDTO, } from "../../service/support/types"; import { getTicket, getTicketStatusTypes, updateTicket, } from "../../service/support"; import { useHistory, useParams } from "react-router-dom"; import InputLabel from "@mui/material/InputLabel"; import Select from "@mui/material/Select"; import MenuItem from "@mui/material/MenuItem"; import { FormControl } from "@mui/material"; import { Moment } from "moment"; import { RouteParams } from "../../service/utils"; export default function TicketProfile(props: any) { const classes = useStyles(); let history = useHistory(); let requestParams = useParamslt;RouteParamsgt;(); const [status, setStatus] = useStatelt;stringgt;(""); const [submitDate, setSubmitDate] = useStatelt;Moment | nullgt;(null); const [ticket, setTicket] = useStatelt;TicketFullDTOgt;(); const formSubmit = async (e: React.FormEventlt;HTMLFormElementgt;) =gt; { e.preventDefault(); console.log(e); updateTicket(requestParams.id, data) .then(({ data }) =gt; { console.log(data.title); history.replace("/support"); }) .catch((err) =gt; { console.log(err); }); }; const [ticketCategoriesList, setTicketCategoriesList] = useStatelt; TicketCategoryTypesDTO[] gt;([]); const [ticket, setTicket] = useStatelt;TicketFullDTOgt;(); const getSingleTicket = async () =gt; { getTicket(requestParams.id) .then(({ data }) =gt; { setTicket(data); }) .catch((error) =gt; { console.error(error); }); }; const [ticketStatusList, setTicketStatusList] = useStatelt; TicketStatusTypesDTO[] gt;([]); useEffect(() =gt; { ticketStatusData(); getSingleTicket(); }, []); const ticketStatusData = async () =gt; { getTicketStatusTypes() .then((resp) =gt; { setTicketStatusList(resp.data); }) .catch((error) =gt; { console.error(error); }); }; return ( lt;Containergt; lt;form onSubmit={onSubmit}gt; ......... lt;TextField value={ticket?.title} id="title" onChange={({ target: { value } }) =gt; { setTicket({ ...ticket, title: value }); }} /gt; ......... lt;FormControlgt; lt;TextField label="Submit Date" id="submit-date" type="date" defaultValue={ticket?.submitDate} //@ts-ignore onInput={(e) =gt; setSubmitDate(e.target.value)} /gt; lt;/FormControlgt; .......... lt;Select labelId="status-label" id="status-helper" value={ticket?.status} onChange={(e) =gt; setStatus(e.target.value)} required gt; {ticketStatusList.map((element) =gt; ( lt;MenuItem value={element.code}gt; {element.name} lt;/MenuItemgt; ))} lt;/Selectgt; lt;/FormControlgt; ........... lt;Button type="submit" gt; Update Ticket lt;/Buttongt; lt;/Containergt; ); } ..... export async function updateTicket( id: string, data: TicketFullDTO ): Promiselt;AxiosResponselt;TicketFullDTOgt;gt; { return await axios.postlt;TicketFullDTOgt;( `${baseUrl}/management/support/tickets/ticket/${id}`, { data, } ); } export interface TicketFullDTO { id?: number, title?: string, status?: string, submitDate?: Moment | null }
Я получаю ошибку:
MUI: A component is changing the uncontrolled value state of Select to be controlled. Elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled Select element for the lifetime of the component. The nature of the state is determined during the first render. It's considered controlled if the value is not
не определено .
Значение для Select
должно быть выбрано с помощью списка значение ticket?.status
при ticketStatusList
, но объект данных не запускается перед отображением содержимого пользовательского интерфейса, и значение в раскрывающемся списке Выбор не выбрано.
Знаете ли вы, как я могу решить эту проблему?
Ответ №1:
Вам нужно указать значение по умолчанию для состояния билета, прямо сейчас оно у вас есть как
const [ticket, setTicket] = useStatelt;TicketFullDTOgt;();
Но, по крайней мере, сделайте его пустым TicketFullDTO
или null