Javascript 使用formik显示字段名列表中的输入字段
我有表单字段名列表,例如Javascript 使用formik显示字段名列表中的输入字段,javascript,reactjs,formik,yup,Javascript,Reactjs,Formik,Yup,我有表单字段名列表,例如list=[“orgName”,“addressLine1”],列表可以是任意长度 我试图使用formik渲染表单,但它抛出了错误 组件正在更改要控制的文本类型的非受控输入。输入元件不应从非受控切换到受控(反之亦然)。在组件的使用寿命内,决定使用受控或非受控输入元件。更多信息: /@flow 从“React”导入React; 从“Formik”导入{Formik,Form,Field}; 从“Yup”导入*作为Yup; 从“./StyledInput”导入{StyledI
list=[“orgName”,“addressLine1”]
,列表可以是任意长度
我试图使用formik
渲染表单,但它抛出了错误
组件正在更改要控制的文本类型的非受控输入。输入元件不应从非受控切换到受控(反之亦然)。在组件的使用寿命内,决定使用受控或非受控输入元件。更多信息:
/@flow
从“React”导入React;
从“Formik”导入{Formik,Form,Field};
从“Yup”导入*作为Yup;
从“./StyledInput”导入{StyledInput};
从“./Span”导入{Span};
从“./Title”导入{Title};
从“./Submit”导入{SubmitButton};
const OrgSignupSchema=Yup.object().shape({
orgName:Yup.string().required(“需要组织名称”),
addressLine1:Yup.string(),
addressLine2:Yup.string(),
状态:Yup.string(),
城市:是的,字符串(),
pin:Yup.string(),
国家:是的,字符串(),
mainterId:Yup.string()
});
接口OrgSignupPayload{
orgName:字符串;
addressLine1?:字符串;
addressLine2?:字符串;
状态?:字符串;
城市?:字符串;
pin?:字符串;
国家?:字符串;
maintainerId?:字符串;
}
接口IOrgSignupProps{
标题?:字符串;
onSubmit:(val:OrgSignupPayload)=>void;
}
导出常量OrgSignupForm=({title,onSubmit}:IOrgSignupProps)=>{
//这些字段是我要渲染的
常量字段=[“orgName”,“addressLine1”];
常量初始状态:OrgSignupPayload={
组织名称:“
};
返回(
{title&&{title}
{
提交时返回(val);
}}
>
{({
错误,
价值观
手推,
handleChange,
感动的,
车把
}) => (
handleSubmit(formVal)}>
{fields&&fields.length
?字段.map((名称、索引)=>(
{innerProps=>{
返回(
{innerProps.form.toucted[名称]&&
innerProps.form.errors[name]&&(
{innerProps.form.errors[name]}
)}
);
}}
))
:null}
提交
)}
);
};
不要怀疑我做错了什么。您没有为输入设置默认值,也没有使用handleChange更新样式化输入中的任何值 您必须为受控输入提供一个默认值(即
value={values.orgName}
),并确保它们具有更改处理程序。使用formik,只要将输入的值绑定到值中相应的值,就可以像onChange={handleChange}
一样简单。如果您没有给您的输入一个值,那么它的值是未定义的,react将其解释为一个非受控组件
有关您与使用withFormik HOC模式方法的人的完全相同问题的详细信息,请参阅此github线程:
我还建议使用withFormik HOC模式,因为我发现它更容易调试,也更不混乱:所以在初始渲染时,您要定义字段=[“orgName”,“addressLine1]代码>。我认为您需要确保
知道在初始值更改时重置表单。因此,添加仍然是相同的问题我想补充一点,作为警告,我的答案通常是好的建议,但您的特定示例有许多活动部件和样式化组件。在将来,一个更简单的示例比直接的复制/粘贴作业要容易得多。我承认样品中有很多垃圾,但有时很有用。我很高兴它对你有用。不知道为什么有人否决了我的答案。答案是有效的,我每天都与Formik/Yup合作,我引用了我的资料来源。但是,无论如何,很高兴我能有所帮助!祝你过得愉快。
// @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>
</>
);
};