我正在尝试将 API 中的值输入到使用 formik 的 TextField MUI 组件中。这个想法是,表单是一个组件,我将它用于另一个组件,其中如果一个值来自 API,那么它会作为 prop 传递给表单组件,如果没有传递,则 TextField 组件是渲染以便手动输入值。
这是来自表单组件的代码片段,其中如果我传递了一个属性,则该值设置为
value
并且 TextField 的 onChange
属性可以设置更新使用 接收到 formik 输入中的值setFieldValue
。我还启用了 formik 上的 enableReinitialize
道具。所有这些都是为了使 isValid
formik 道具识别该值有效并启用提交按钮。
// FormComponent
onst valSchema = Yup.object().shape({
batchNo: Yup.string()
.required('Required'),
item: Yup.string().required('Required'),
price: Yup.string().required('Required'),
});
const ItemForm = (props) => {
return (
<Grid container>
<Grid item xs={12}>
<Container maxWidth="md">
<div>
<Formik
enableReinitialize
initialValues={initialValues}
validationSchema={valSchema}
onSubmit={(values) => {
localHandleSubmit(values);
}}
>
{({ dirty, isValid, errors, handleChange, setFieldValue }) => (
<Form>
<Grid container spacing={2}>
{props.batchValue ? (
<Grid item xs={12}>
<TextField name="batchNo" label="Batch No" value={props.batchValue} onChange={(e) => {
handleChange(e);
setFieldValue('batchNo', props.batchValue);}} />
</Grid>
) : (
<Grid item xs={12}>
<TextField name="batchNo" label="Batch No" />
</Grid>
)}
<Grid item xs={6}>
<TextField name="item" label="Item" />
</Grid>
<Grid item xs={6}>
<TextField name="price" label="Price" />
</Grid>
<Grid item xs={12}>
<Button
fullWidth
variant="contained"
disabled={!isValid || !dirty}
type="submit"
>
{' '}
ADD
</Button>
</Grid>
</Grid>
</Form>
)}
</Formik>
</div>
</Container>
</Grid>
</Grid>
);
};
这就是我将值传递给表单组件的方式。
<DialogContent dividers>
<FormComponent batchValue={batch} />
</DialogContent>
我遇到的问题是提交按钮未启用,因此我发现 isValid formik 属性为 false 并且需要该值的错误,因此 formik 无法将从 API 传递的值识别为有效。
我想知道如何才能完成这项工作。
我知道这个问题很久以前就被问过,但这可能对某人有帮助。技巧是使用
initialValues
对象设置输入值,并使用空字符串回退到普通的可编辑输入。
// Suppose data is the prop returned from an API response
const data = {
batchNo: "04930",
item: "Gizmo",
price: "24.43",
};
<Formik
enableReinitialize
initialValues={{
batchNo: data?.batchNo ?? "",
item: data?.item ?? "",
price: data?.price ?? ""
}}
validationSchema={valSchema}
onSubmit={(values) => {
localHandleSubmit(values);
}}
/>
现在输入字段的默认值将是来自 API 属性的值。通过利用
??
无效合并运算符,当响应未定义时,我们回退到空的可编辑输入。
要将值输入到输入中,您可以使用 formik
values
对象,而不是直接传递 prop 数据。
{({ dirty, isValid, errors, handleChange, setFieldValue, values }) => (
<Form>
<Grid container spacing={2}>
{values.batchNo ? (
<Grid item xs={12}>
<TextField
name="batchNo"
label="Batch No"
value={values.batchNo}
onChange={(e) => {
handleChange(e);
setFieldValue("batchNo", values.batchNo);
}}
/>
</Grid>
) : (
<Grid item xs={12}>
<TextField
name="batchNo"
label="Batch No"
value={values.batchNo}
onChange={(e) => setFieldValue("batchNo", values.batchNo)}
/>
</Grid>
)}
<Grid item xs={6}>
<TextField
name="item"
label="Item"
value={values.item}
onChange={(e) => setFieldValue("item", values.item)}
/>
</Grid>
<Grid item xs={6}>
<TextField
name="price"
label="Price"
value={values.price}
onChange={(e) => setFieldValue("item", values.price)}
/>
</Grid>
<Grid item xs={12}>
<Button
fullWidth
variant="contained"
disabled={!isValid || !dirty}
type="submit"
>
{" "}
ADD
</Button>
</Grid>
</Grid>
</Form>
)}