我像这样使用带有前向引用的 formik 形式
表单.js
import React from "react";
import FormikWithRef from "./FormikWithRef";
const Form = ({
formRef,
children,
initialValues,
validationSchema,
onSubmit
}) => {
return (
<FormikWithRef
validateOnChange={true}
validateOnBlur={true}
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={onSubmit}
ref={formRef}
>
{(props) => <form onSubmit={props.handleSubmit}>{children}</form>}
</FormikWithRef>
);
};
export default Form;
FormikWithRef.js
import React, { forwardRef, useImperativeHandle } from "react";
import { Formik } from "formik";
function FormikWithRef(props, ref) {
let _formikProps = {};
useImperativeHandle(ref, () => _formikProps);
return (
<Formik {...props}>
{(formikProps) => {
_formikProps = formikProps;
if (typeof props.children === "function") {
return props.children(formikProps);
}
return props.children;
}}
</Formik>
);
}
export default forwardRef(FormikWithRef);
我有一些选项卡,更新 easy-peasy
存储状态 type
,当我选择第二个选项卡时,我想更新输入值(最初来自 value
的存储状态 ---
) with a Formik form, but updating state initialValues
specific to that component that gets passed as initialValues
prop to the Formik
component.
TabsForm.js
import React, { useState, useEffect, useRef } from "react";
import styled from "styled-components";
import { useStoreState } from "easy-peasy";
import Form from "./Form";
import MoneyBox from "./MoneyBox";
const Container = styled.div`
width: 100%;
background-color: #dfdfdf;
`;
const FieldWrapper = styled.div`
padding: 20px 12px;
`;
const TabsForm = () => {
const [initialValues, setInitialValues] = useState();
const type = useStoreState((state) => state.type);
const value = useStoreState((state) => state.value);
const formRef = useRef(null);
const onFormSubmit = async (values) => {
console.log({ values });
};
useEffect(() => {
if (value && type) {
let filterVal = { ...value };
/* here is where I update the input value to be 3000,
the initial values get updated and in the `Form.js` file,
the console log from here also reflects this update,
however, the input field does not update? */
if (type === "Two") filterVal.input = 30000;
setInitialValues(filterVal);
}
}, [value, type]);
useEffect(() => {
// check initialValues has updated
console.log({ initialValues });
}, [initialValues]);
return (
<Container>
{initialValues && type ? (
<Form
initialValues={initialValues}
onSubmit={onFormSubmit}
formRef={formRef}
>
<FieldWrapper>
<MoneyBox name="input" currencySymbol={"£"} />
</FieldWrapper>
</Form>
) : null}
</Container>
);
};
export default TabsForm;
单击第二个选项卡时;
initialValues
状态TabsForms.js
更新使得value.input
=30000
;- The
initialValues
prop in bothForm.js
andFormikWithRef.js
also reflect thatvalue.input
=3000
- However, the input does not update, using the
useField
hook fromforimk
in theMoneyBox.js
component, thefield
object does not have avalue
的30000
,而不是以前的字段值,这是为什么?
我创建了一个 CodeSandbox 来查看所有使用的组件,并创建了控制台日志以查看 Formik 确实收到了更新的值,但似乎没有应用它。
我已经坚持了几天,似乎找不到解决方案,我们将不胜感激。
原文由 mcclosa 发布,翻译遵循 CC BY-SA 4.0 许可协议
If you want the value of the input to change when you change
initialValues
, you need to pass to theFormik
component the propenableReinitialize
astrue
。因此,您需要在代码中更改的是
TabsForm.js
传递给您的Form
组件 propenableReinitialize
在你的
Form.js
中将该道具传递给Formik
组件我不太确定您的业务逻辑应该如何工作,但这是一个包含上述更改的 工作示例。