javascript - 在 Formik Form 上更新 initialValues Prop 不会更新输入值

标签 javascript reactjs formik

我使用带有前向引用的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 ,当我选择第二个选项卡时,我想用 Formik 表单更新输入值(最初来自 value 的存储状态),但更新状态 initialValues特定于作为 initialValues 传递的组件支持 Formik零件。
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 ;
  • initialValues支持Form.jsFormikWithRef.js也反射(reflect)value.input = 3000
  • 但是,输入不会更新,使用 useField来自 forimk 的钩子(Hook)在 MoneyBox.js组件,field对象没有 value30000 ,而是之前的字段值,这是为什么呢?

  • 我创建了一个 CodeSandbox查看所有使用的组件,并通过控制台日志查看 Formik 确实收到了更新的值,但似乎没有应用它。
    我已经坚持了几天,似乎无法找到解决方案,任何帮助将不胜感激。

    最佳答案

    如果您希望在更改 initialValues 时更改输入的值,您需要传递给 Formik组件 Prop enableReinitialize true .
    因此,您需要更改的代码在 TabsForm.js传递给您的Form组件 Prop enableReinitialize

    <Form
      enableReinitialize
      initialValues={initialValues}
      onSubmit={onFormSubmit}
      formRef={formRef}
    >
      <FieldWrapper>
        <MoneyBox name="input" currencySymbol={"£"} />
      </FieldWrapper>
    </Form>
    
    在您的 Form.js将该 Prop 传递给 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与上述更改。

    关于javascript - 在 Formik Form 上更新 initialValues Prop 不会更新输入值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63287980/

    相关文章:

    reactjs - 如何根据另一个表单字段动态显示隐藏 Formik 表单字段

    javascript - Jquery中有内置方法吗?

    JavaScript 抛出未定义的错误

    javascript - 我需要 js 中的一些 lib 来显示 3d 模型

    javascript - 根据 React.Js 中第一个下拉列表中的选择填充第二个下拉列表

    javascript - React Formik 复选框组不会变成单个选中或未选中元素的数组

    javascript - 如何使用 Mustache 模板向下拉列表添加选项?

    javascript - 如何使用倒计时器停止弹出窗口显示多次

    javascript - 如何为我的 React 应用程序解决 "Element type is invalid"?

    reactjs - React Formik 给出 Cannot read properties of undefined (reading 'fullName') 错误