问题描述
我对前向裁判使用Forik形式,如下所示
Form.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,当我选择第二个选项卡时,我想用Formik表单更新输入值(最初来自value存储状态),但更新特定于作为initialValues属性传递给Formik组件组件的状态。
TabForm.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;
单击第二个选项卡时;
- TabsForms.js中的initialValues状态更新为value.input=30000; 和中属性也反映了<[2-8]=
- 但是,输入没有更新,使用MoneyBox.js组件中的useField钩子MoneyBox.js,field对象没有value的30000,而是之前的任何字段值,这是为什么?
我已创建CodeSandbox以查看所有使用的组件,并创建控制台日志以查看Formik确实接收到更新的值,但似乎未应用它。
我已经在这个问题上纠结了几天,似乎找不到解决方案,如果有任何帮助,我将不胜感激。
推荐答案
如果希望在更改initialValues时更改输入值,则需要将道具enableReinitialize作为true传递给Formik组件。
因此,您需要在代码中更改的是TabsForm.js传递给Form组件的属性enableReinitialize
<Form enableReinitialize initialValues={initialValues} onSubmit={onFormSubmit} formRef={formRef} > <FieldWrapper> <MoneyBox name="input" currencySymbol={"£"} /> </FieldWrapper> </Form>并在Form.js中将该道具传递给Formik组件
const Form = ({ formRef, children, initialValues, validationSchema, onSubmit, enableReinitialize }) => { return ( <FormikWithRef enableReinitialize={enableReinitialize} validateOnChange={true} validateOnBlur={true} initialValues={initialValues} validationSchema={validationSchema} onSubmit={onSubmit} ref={formRef} > {(props) => <form onSubmit={props.handleSubmit}>{children}</form>} </FormikWithRef> ); };
我不太确定您的业务逻辑应该如何工作,但以下是对上述更改的working example。