Javascript 如何将Formik字段组件抽象为通用共享组件
我试图将formik组件抽象成一个单独的文件,这样我就可以在不同的表单中重用它,当我将组件分解成一个单独的文件并将其导入表单时,我遇到了一个错误(见下文)。在自定义组件中使用组件或passign可以正常工作,但导入它会引发错误。任何帮助都将不胜感激-克里斯 我尝试了多种方法(我的代码反映了哪些有效,哪些无效)。我已经翻遍了这些文档,在谷歌上搜索了很多,没有找到将组件抽象成单独文件的好例子Javascript 如何将Formik字段组件抽象为通用共享组件,javascript,reactjs,formik,Javascript,Reactjs,Formik,我试图将formik组件抽象成一个单独的文件,这样我就可以在不同的表单中重用它,当我将组件分解成一个单独的文件并将其导入表单时,我遇到了一个错误(见下文)。在自定义组件中使用组件或passign可以正常工作,但导入它会引发错误。任何帮助都将不胜感激-克里斯 我尝试了多种方法(我的代码反映了哪些有效,哪些无效)。我已经翻遍了这些文档,在谷歌上搜索了很多,没有找到将组件抽象成单独文件的好例子 // Test-form.tsx import React from "react"; import { F
// Test-form.tsx
import React from "react";
import { FormikTextField, CustomComponent } from "@cleaved/formik";
import { Form, Field, ErrorMessage, Formik, FormikActions } from "formik";
type TestFormProps = {
address: string;
name: string;
phone: string;
};
export const TestForm = () => {
return (
<>
<Formik
initialValues={{ address: "", name: "Chris Campbell", phone: "" }}
onSubmit={(values: TestFormProps, actions: FormikActions<TestFormProps>) => {
actions.setSubmitting(false);
}}
>
{({ touched, errors, isSubmitting }) => (
<Form>
{/* 1 works */}
<div className="form-group">
<label htmlFor="name">Name: </label>
<Field
type="text"
name="name"
placeholder="name"
className={`form-control ${touched.name && errors.name ? "is-invalid" : ""}`}
/>
<ErrorMessage component="div" name="name" className="invalid-feedback" />
</div>
{/* 2 works */}
<Field
label="Phone: "
name="phone"
placeholder="enter phone number"
type="text"
component={CustomComponent}
/>
{/* 3 doesn't work */}
<FormikTextField label="address: " name="address" placeholder="enter address" type="text" />
<button type="submit" className="btn btn-primary btn-block" disabled={isSubmitting}>
{isSubmitting ? "Please wait..." : "Submit"}
</button>
</Form>
)}
</Formik>
</>
);
};
//Test-form.tsx
从“React”导入React;
从“@cleaved/formik”导入{FormikTextField,CustomComponent};
从“Formik”导入{Form,Field,ErrorMessage,Formik,FormikActions};
类型TestFormProps={
地址:字符串;
名称:字符串;
电话:字符串;
};
导出常量TestForm=()=>{
返回(
{
动作。设置提交(错误);
}}
>
{({触摸,错误,提交})=>(
{/*1作品*/}
姓名:
{/*2工程*/}
{/*3不起作用*/}
{提交?“请稍候…”:“提交”}
)}
);
};
//formik-textbox.sx
从“React”导入React;
从“formik”导入{Field,FieldProps};
//2个作品
导出类型CustomComponentProps={
标签?:字符串;
名称:字符串;
占位符?:字符串;
键入:“文本”|“密码”;
};
导出常量自定义组件=({
标签,
名称
占位符,
类型,
表单:{toucted,errors},//还有值,setXXXX,handlexxx,dirty,isValid,status,等等。
…道具
}:any)=>(
{label}
{触摸[name]&&errors[name]&&{errors[name]}
);
//3不起作用
导出类型FormikTextFieldProps={
标签?:字符串;
名称:字符串;
占位符?:字符串;
键入:“文本”|“密码”;
};
export const FormikTextField:React.FC=({标签、名称、占位符、类型})=>(
{({field,form:{toucted,errors}}}:FieldProps)=>{
返回(
{label}
{触摸[name]&&errors[name]&&{errors[name]}
);
}}
);
导入组件(#3)时收到的错误消息如下:
未捕获类型错误:this.props.formik.registerField不是函数
在FieldInner.componentDidMount(formik.esm.js:811)
在提交周期(react dom.development.js:17334)
在提交生命周期(react dom.development.js:18736)
在htmlunknowneelement.callCallback(react dom.development.js:149)
在Object.invokeGuardedCallbackDev(react dom.development.js:199)
在invokeGuardedCallback(react dom.development.js:256)
在Commitrout(react dom.development.js:18948)
在react dom.development.js:20418
在Object.unstability\u runWithPriority(scheduler.development.js:255)
在completeRoot(react dom.development.js:20417)
在PerformWorkRoot(react dom.development.js:20346)
在performWork上(react dom.development.js:20254)
在performSyncWork(react dom.development.js:20228)
在requestWork(react dom.development.js:20097)
在scheduleWork(react dom.development.js:19911)
在scheduleRootUpdate上(react dom.development.js:20572)
在UpdateContainerExpirationTime(react dom.development.js:20600)
在updateContainer(react dom.development.js:20657)
在ReactRoot.dll_244e94d4223562f55cdd…/../../../node_modules/react-dom/cjs/react-dom.development.js.ReactRoot.render(react-dom.development.js:20953)
在react dom.development.js:21090
在未分段更新时(react dom.development.js:20459)
在legacyRenderSubtreeIntoContainer(react dom.development.js:21086)
在Object.hydroge(react dom.development.js:21148)
在renderReactElement(index.js:31)
at_callee4$(index.js:35)
在tryCatch(runtime.js:45)
在Generator.invoke[as_invoke](runtime.js:271)
在发电机上。原型。[作为下一个](runtime.js:97)
在asyncGeneratorStep(asyncToGenerator.js:5)
at_next(asyncToGenerator.js:27)
在asyncToGenerator.js:34
在新的承诺()
在新的F(_export.js:36)
在asyncToGenerator.js:23
at_doRender(索引js:35)
在多伦德(索引:31)
at_callee2$(index.js:23)
在tryCatch(runtime.js:45)
在Generator.invoke[as_invoke](runtime.js:271)
在发电机上。原型。[作为下一个](runtime.js:97)
在asyncGeneratorStep(asyncToGenerator.js:5)
at_next(asyncToGenerator.js:27)
在asyncToGenerator.js:34
在新的承诺()
在新的F(_export.js:36)
在asyncToGenerator.js:23
at_render(index.js:23)
渲染时(index.js:20)
at_callee$(index.js:20)
在tryCatch(runtime.js:45)
toucted[name]&errors[name]
您正在将“address”作为名称传递,因此toucted或errors未定义。堆栈跟踪告诉您问题所在和正确的查找位置,不确定我们还可以添加什么。抱歉,我得到的真正错误是:Uncaught TypeError:this.props.formik.registerField不是函数。我更新了我的stacktrace。你正在使用所有功能组件,这个来自哪里?我不知道。我的代码中没有引用“this”。我认为这与Formik如何注册它的字段组件有关。前两个实现按预期工作。因为某种原因,第三个没有。不过我真的不确定。
// formik-textbox.sx
import React from "react";
import { Field, FieldProps } from "formik";
// 2 works
export type CustomComponentProps = {
label?: string;
name: string;
placeholder?: string;
type: "text" | "password";
};
export const CustomComponent = ({
label,
name,
placeholder,
type,
form: { touched, errors }, // also values, setXXXX, handleXXXX, dirty, isValid, status, etc.
...props
}: any) => (
<div>
<label>{label}</label>
<input type={type} name={name} placeholder={placeholder} />
{touched[name] && errors[name] && <div className="error">{errors[name]}</div>}
</div>
);
// 3 doesn't work
export type FormikTextFieldProps = {
label?: string;
name: string;
placeholder?: string;
type: "text" | "password";
};
export const FormikTextField: React.FC<FormikTextFieldProps> = ({ label, name, placeholder, type }) => (
<Field name={name}>
{({ field, form: { touched, errors } }: FieldProps) => {
return (
<div>
<label>{label}</label>
<input type={type} name={name} placeholder={placeholder} />
{touched[name] && errors[name] && <div className="error">{errors[name]}</div>}
</div>
);
}}
</Field>
);
The error message I'm receiving when importing the <Field /> component (#3) is below:
Uncaught TypeError: this.props.formik.registerField is not a function
at FieldInner.componentDidMount (formik.esm.js:811)
at commitLifeCycles (react-dom.development.js:17334)
at commitAllLifeCycles (react-dom.development.js:18736)
at HTMLUnknownElement.callCallback (react-dom.development.js:149)
at Object.invokeGuardedCallbackDev (react-dom.development.js:199)
at invokeGuardedCallback (react-dom.development.js:256)
at commitRoot (react-dom.development.js:18948)
at react-dom.development.js:20418
at Object.unstable_runWithPriority (scheduler.development.js:255)
at completeRoot (react-dom.development.js:20417)
at performWorkOnRoot (react-dom.development.js:20346)
at performWork (react-dom.development.js:20254)
at performSyncWork (react-dom.development.js:20228)
at requestWork (react-dom.development.js:20097)
at scheduleWork (react-dom.development.js:19911)
at scheduleRootUpdate (react-dom.development.js:20572)
at updateContainerAtExpirationTime (react-dom.development.js:20600)
at updateContainer (react-dom.development.js:20657)
at ReactRoot.dll_244e94d4223562f55cdd.../../../node_modules/react-dom/cjs/react-dom.development.js.ReactRoot.render (react-dom.development.js:20953)
at react-dom.development.js:21090
at unbatchedUpdates (react-dom.development.js:20459)
at legacyRenderSubtreeIntoContainer (react-dom.development.js:21086)
at Object.hydrate (react-dom.development.js:21148)
at renderReactElement (index.js:31)
at _callee4$ (index.js:35)
at tryCatch (runtime.js:45)
at Generator.invoke [as _invoke] (runtime.js:271)
at Generator.prototype.<computed> [as next] (runtime.js:97)
at asyncGeneratorStep (asyncToGenerator.js:5)
at _next (asyncToGenerator.js:27)
at asyncToGenerator.js:34
at new Promise (<anonymous>)
at new F (_export.js:36)
at asyncToGenerator.js:23
at _doRender (index.js:35)
at doRender (index.js:31)
at _callee2$ (index.js:23)
at tryCatch (runtime.js:45)
at Generator.invoke [as _invoke] (runtime.js:271)
at Generator.prototype.<computed> [as next] (runtime.js:97)
at asyncGeneratorStep (asyncToGenerator.js:5)
at _next (asyncToGenerator.js:27)
at asyncToGenerator.js:34
at new Promise (<anonymous>)
at new F (_export.js:36)
at asyncToGenerator.js:23
at _render (index.js:23)
at render (index.js:20)
at _callee$ (index.js:20)
at tryCatch (runtime.js:45)