reactjs - 如何在 useEffect 挂钩中形成 setFieldValue
问题描述
我有一个 Formik 表单,需要根据通过路由器传递的信息动态更改。我需要运行 graphQL 查询来检索一些数据并使用检索到的数据填充表单。我能够设置表单并检索数据,但我无法弄清楚如何在 useEffect 挂钩中为基础表单设置字段值。我觉得我错过了一些重要的部分来访问 Formik 上下文,但我无法从文档中找到它。
任何帮助都会很棒。
import React, { useState, useEffect } from "react";
import Router, { useRouter } from "next/router";
import Container from "react-bootstrap/Container";
import { Field, Form, FormikProps, Formik } from "formik";
import * as Yup from "yup";
import { useLazyQuery } from "@apollo/react-hooks";
import { GET_PLATFORM } from "../graphql/platforms";
export default function platformsForm(props) {
const router = useRouter();
// grab the action requested by caller and the item to be updated (if applicable)
const [formAction, setFormAction] = useState(router.query.action);
const [formUpdateId, setFormUpdateId] = useState(router.query.id);
const [initialValues, setInitialValues] = useState({
platformName: "",
platformCategory: ""
});
const validSchema = Yup.object({
platformName: Yup.string().required("Name is required"),
platformCategory: Yup.string().required("Category is required")
});
const [
getPlatformQuery,
{ loading, error, data: dataGet, refetch, called }
] = useLazyQuery(GET_PLATFORM, {
variables: { id: formUpdateId }
});
useEffect(() => {
!called && getPlatformQuery({ variables: { id: formUpdateId } });
if (dataGet && dataGet.Platform.platformName) {
console.log(
dataGet.Platform.platformName,
dataGet.Platform.platformCategory
);
//
// vvv How do I set Field values at this point if I don't have Formik context
// setFieldValue();
//
}
}),
[];
const onSubmit = async (values, { setSubmitting, resetForm }) => {
console.log("submitted");
resetForm();
setSubmitting(false);
};
return (
<Container>
<Formik
initialValues={initialValues}
validationSchema={validSchema}
onSubmit={onSubmit}
>
{({
handleSubmit,
handleChange,
handleBlur,
handleReset,
values,
touched,
isInvalid,
isSubmitting,
isValidating,
submitCount,
errors
}) => (
<Form>
<label htmlFor="platformName">Name</label>
<Field name="platformName" type="text" />
<label htmlFor="platformCategory">Category</label>
<Field name="platformCategory" type="text" />
<button type="submit">Submit</button>
</Form>
)}
</Formik>
</Container>
);
}
解决方案
我想我想通了,但不确定。我发现一些地方提到了一个 Formik innerRef 道具,所以尝试了一下,它似乎有效。我在文档或教程中都没有提到它,所以我不确定这是否是一些不受支持的功能,或者可能只是应该用于内部 Formik 的东西,但它似乎对我有用所以我将使用它,直到找到更好的方法。我已经花了更长的时间来分享我想要分享的内容。:|
欢迎提出意见或建议。或者,如果您认为这是正确的方法,则可以投票。
为了解决这个问题,我在函数主体中添加了一个 useRef:
const formikRef = useRef();
然后我将其添加为道具:
<Formik
innerRef={formikRef}
initialValues={initialValues}
validationSchema={validSchema}
onSubmit={onSubmit}
>
一旦我这样做了,我就可以从 useEffect 中引用 Formik 函数,所以在我的情况下,我做了以下事情:
if (formikRef.current) {
formikRef.current.setFieldValue(
"platformName",
dataGet.Platform.platformName
);
formikRef.current.setFieldValue(
"platformCategory",
dataGet.Platform.platformCategory
);
}
推荐阅读
- postgresql - 如何在 PSQL 和 pgAdmin 之间同步数据库
- nativescript - nativescript iOS 构建失败
- python - Pandas/Numpy NaN 无比较
- c - 编译时检查是否所有数组成员都已初始化
- powershell - 这些文件名来自哪里?
- project-reactor - 当数字不固定时,合并来自多个 Monos 的结果?
- javascript - 角度5将图像转换为base64
- python - 在 Python 标准输出中测试新行
- excel - 在对行数据进行重复数据删除时,如何*有效地*对动态列数中的整数求和?
- azure - 设置 kubernetes 集群时,kubeadm 初始化命令出错