使用formik显示字段名称列表中的输入字段

时间:2020-01-20 18:57:40

标签: javascript reactjs formik yup

我有表单字段名称的列表,例如list = ["orgName", "addressLine1"],列表可以是任意长度。

我尝试使用formik渲染表单,但是会引发错误

一个组件正在更改要控制的文本类型的不受控制的输入。输入元素不应从不受控制切换为受控制(反之亦然)。确定在组件的使用寿命期间使用受控或不受控制的输入元素。更多信息:

// @flow
import React from "react";
import { Formik, Form, Field } from "formik";
import * as Yup from "yup";

import { StyledInput } from "../StyledInput";
import { Span } from "../Span";
import { Title } from "../Title";
import { SubmitButton } from "../Submit";

const OrgSignupSchema = Yup.object().shape({
  orgName: Yup.string().required("org name is required"),
  addressLine1: Yup.string(),
  addressLine2: Yup.string(),
  state: Yup.string(),
  city: Yup.string(),
  pin: Yup.string(),
  country: Yup.string(),
  maintainerId: Yup.string()
});

interface OrgSignupPayload {
  orgName: string;
  addressLine1?: string;
  addressLine2?: string;
  state?: string;
  city?: string;
  pin?: string;
  country?: string;
  maintainerId?: string;
}

interface IOrgSignupProps {
  title?: string;
  onSubmit: (val: OrgSignupPayload) => void;
}

export const OrgSignupForm = ({ title, onSubmit }: IOrgSignupProps) => {

  // These fields i want to render
  const fields = ["orgName", "addressLine1"];

  const initialState: OrgSignupPayload = {
    orgName: ""
  };

  return (
    <>
      {title && <Title>{title}</Title>}
      <Formik
        initialValues={initialState}
        validationSchema={OrgSignupSchema}
        onSubmit={(val: OrgSignupPayload) => {
          return onSubmit(val);
        }}
      >
        {({
          errors,
          values,
          handleSubmit,
          handleChange,
          touched,
          handleBlur
        }) => (
          <Form onSubmit={formVal => handleSubmit(formVal)}>
            {fields && fields.length
              ? fields.map((name, index) => (
                  <React.Fragment key={name}>
                    <Field name={name}>
                      {innerProps => {
                        return (
                          <>
                            <StyledInput
                              {...innerProps.field}
                              title={name}
                              type="text"
                            />
                            {innerProps.form.touched[name] &&
                              innerProps.form.errors[name] && (
                                <Span small red>
                                  {innerProps.form.errors[name]}
                                </Span>
                              )}
                          </>
                        );
                      }}
                    </Field>
                  </React.Fragment>
                ))
              : null}

            <br />
            <br />
            <SubmitButton type="submit" rounded>
              Submit
            </SubmitButton>
          </Form>
        )}
      </Formik>
    </>
  );
};


别在哪里做错了。

1 个答案:

答案 0 :(得分:0)

您既不会为输入设置默认值,也不会使用handleChange从样式输入中更新任何值。

您必须为受控输入提供默认值(即added_files = [ ( './pics/*', 'pics' ), ( './db/*', 'db' ), ] ),并确保它们具有更改处理程序。使用formik,一旦将输入的值绑定到datas = added_files 中的相应值,就如同value={values.orgName}一样简单。如果您没有为输入提供值,则该值是不确定的,然后react将其解释为不受控制的组件

请参阅此github线程,以了解与使用withFormik HOC模式方法的人完全相同的问题的详细信息:https://github.com/jaredpalmer/formik/issues/28

我还建议使用withFormik HOC模式,因为我发现它更容易调试并且更不会混乱:https://jaredpalmer.com/formik/docs/api/withFormik