reactjs–REACT–从API获取后,在Formik Form中设置初始数据



寻求帮助-我试图在从API获取后处理formik中的初始数据,表单读取初始值,但在获取后没有。我正在使用useEffect。此外,我正在使用文档addEventListener来处理输入搜索keydown事件,我知道在React中,如果有任何正文检查代码并给出表单中的问题以及如何处理带状态的输入搜索引用,这不是最佳实践。

import React, { useEffect, useState } from 'react';
import { Formik, Form, FastField } from 'formik';
import SearchOutlinedIcon from "@mui/icons-material/SearchOutlined";
import * as yup from 'yup';
import axios from 'axios';
import "./edit.scss";
import Loading from "../Loading";
import Swal from 'sweetalert2';
const validation = yup.object().shape({
emp_no: yup.number().required(""),
name: yup.string().required(""),
project: yup.string().required(""),
nationality: yup.string().required(""),
iqama_no: yup.number().required(""),
room_no: yup.number().required(""),
zoon_no: yup.number().required(""),
in_date: yup.date().required(""),
in_reason: yup.string().required(""),
out_date: yup.date()
});
const initialValues = {
emp_no: "",
name: "",
project: "",
nationality: "",
iqama_no: "",
room_no: "",
zoon_no: "",
in_date: "",
in_reason: "",
out_date: "",
};
const EditAlameia = () => {
const [query, setQuery] = useState("");
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
const fetchData = async (event) => {
if (event.keyCode === 13) {
event.preventDefault();
setLoading(true);
await axios.get(`http://localhost:3001/alameia/search/edit?q=${query}`).then((res) => {
console.log(res.data);
setData(res.data);
}).catch((err) => {
if (err.response) {
console.log(err.response.data);
console.log(err.response.status);
} else if (err.request) {
console.log(err.request);
} else {
console.log('Error', err.message);
}
}).finally(() => setLoading(false));
}
};
document.addEventListener('keydown', fetchData);
return () => {
document.removeEventListener('keydown', fetchData);
}
}, [query]);
if (loading) {
return (
<Loading />
)
}
return (
<div className="searchNew">
<div className="top">
<h5 >Edit Data</h5>
<div className="searchInput">
<input
type="text"
placeholder="بحث"
id="search"
value={query}
onChange={(e) => { setQuery(e.target.value) }}
/>
<SearchOutlinedIcon />
</div>
</div>
{(data !== undefined) ?
<Formik
initialValues={data || initialValues}
validationSchema={validation}
enableReinitialize
>
{formik => {
console.log(data)
return (
<Form encType='multipart/form-data'>
<div className="bottom">
<div className="right">
<label htmlFor="emp_no" >الرقم الوظيفي</label>
<FastField
type='number'
name='emp_no'
id="emp_no"
/>
<label htmlFor="name" >الإسم</label>
<FastField
type='text'
name='name'
id="name"
/>
<label htmlFor="project" >المشروع </label>
<FastField
type='text'
name='project'
id="project"
/>
<label htmlFor="nationality" >الجنسية </label>
<FastField
type='text'
name='nationality'
id="nationality"
/>
<button type='submit' className="btn btn-danger" >Update</button>
</div>
<div className="left">
<div className="room">
<label htmlFor="room">رقم </label>
<FastField
autoComplete="off"
className="formInput"
type="number" id="room_no" name="room_no" placeholder=""
/>
<label htmlFor="zoon">زون </label>
<FastField
className="formInput" type="number" id="zoon_no"
name="zoon_no" placeholder=""
/>
</div>
<label htmlFor="in_date">تاريخ التسكين</label>
<FastField
type='date'
name='in_date'
id="in_date"
/>
<label htmlFor="iqama_no" >رقم الإقامة </label>
<FastField
type='number'
name='iqama_no'
id="iqama_no"
/>
<label htmlFor="in_reason" >سبب التسكين</label>
<FastField
type='text'
name='in_reason'
id="in_reason"
/>
<label htmlFor="out_date" >تاريخ الخروج</label>
<FastField
type='date'
name='out_date'
id="out_date"
/>
</div>
</div>
</Form>
)
}}
</Formik>
:<div style={{fontSize: "14px", color:"crimson"}}>Not available</div>            
}
</div>
)
}
export default EditAlameia;

我不确定这是否解决了您的问题,但我目前在您的组件中看到的主要问题是您正在使用addEventListener()

您可以将<input>放在<form>(在Enter上提交(中,并通过React添加onSubmit事件,而不是侦听"keydown"事件并检查Enter(例如keyCode13(。

.spinner {
/* just to push the spinner away from the search bar */
margin-top: 1em;
width: 2em;
height: 2em;
border-top: 2px solid black;
border-radius: 50%;
animation: 1s linear infinite spin;
}
@keyframes spin {
from { transform: rotate(0turn) }
to   { transform: rotate(1turn) }
}
/* keep the snippet console small */
div.as-console-wrapper { max-height: calc(1em + 9px) }
<script type="text/babel">
const { useState } = React;
const SPOOF_DATA = [
{ id: 1, label: "John Doe"    },
{ id: 2, label: "Jane Doe"    },
{ id: 3, label: "foo"         },
{ id: 4, label: "foo bar"     },
{ id: 5, label: "foo bar baz" },
{ id: 6, label: "yo"          },
];
const sleep     = ms    => new Promise(resolve => setTimeout(resolve, ms));
const randomInt = limit => Math.floor(Math.random() * limit);
function Loading() {
return <div className="spinner" />;
}
function App() {
const [query,     setQuery    ] = useState("");
const [isLoading, setIsLoading] = useState(false);
const [data,      setData     ] = useState([]);

async function fetchSearchResults(e) {
e.preventDefault();

setIsLoading(true);
try {
console.log("fetch data using query", JSON.stringify(query));
// const res = await axios.get(`http://localhost:3001/alameia/search/edit?q=${query}`);
// setData(res.data);
await sleep(1000 + randomInt(2000));
setData(SPOOF_DATA.filter(({ label }) => label.includes(query)));
} catch (err) {
if (err.response) {
console.log(err.response.data);
console.log(err.response.status);
} else if (err.request) {
console.log(err.request);
} else {
console.log('Error', err.message);
}
} finally {
setIsLoading(false);
}
}
return (
<>
<form onSubmit={fetchSearchResults}>
<input value={query} onChange={e => setQuery(e.target.value)} />
</form>
{isLoading ? (
<Loading />
) : (
<ul>
{data.map(({ id, label }) => (
<li key={id}>{label}</li>
))}
</ul>
)}
</>    
);
}
ReactDOM.createRoot(document.querySelector("#root")).render(<App />);
</script>
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script crossorigin src="https://unpkg.com/@babel/standalone@7/babel.min.js"></script>
<div id="root"></div>

最新更新