reactjs - React-hook-form:递归注入 props 到嵌套的自定义字段
问题描述
我想使用 react-hook-form 设置一个自定义Form
组件,该组件可以处理可能嵌套或包装在其他元素中的字段。我的方法是遍历组件树并递归地将register
和errors
(由 useForm() 返回)传递给作为输入字段的所有叶节点。
例如,一个简单的注册表单。名字和姓氏字段被包装在一个 div 中,将它们设置在同一行上。表格如下所示:
<Form
onSubmit={onSubmit}
styles={["login_form"]}
showButton
buttonText='SIGN UP'>
// These are the wrapped fields
<div className='signup_name_field'>
<TextInput name={"fname"} label={"first"} />
<TextInput name={"lname"} label={"last"} />
</div>
<TextInput name={"email"} label={"email"} />
<TextInput password={true} name={"password"} label={"password"} />
<TextInput
password={true}
name={"passwordConfirm"}
label={"confirm password"}
/>
</Form>
我按照 react-hook-form 的示例创建了一个自定义表单组件,但添加了一个递归函数来处理嵌套或包装的字段:
const recursiveInjectProps: any = (children: any) => {
return React.Children.map(children, (child) => {
if (child.props.children) {
recursiveInjectProps(child.props.children);
return child;
} else {
if (child.props.name) {
return React.createElement(child.type, {
...{
...child.props,
register: register,
key: child.props.name,
},
});
} else {
return child;
}
}
});
};
return (
<form className={styles.join(" ")} onSubmit={handleSubmit(onSubmit)}>
{recursiveInjectProps(children)}
{renderButton()}
</form>
);
TextInput 看起来像这样:
const checkRegister = () => {
if (register) {
return (
<div className='login_field'>
<input
className='login_input'
name={name}
placeholder={label}
ref={register(validation)}
type={password ? "password" : "text"}
{...rest}
/>
<label htmlFor={name} className='login_label' />
{errors && errors[name] && errors[name].message}
</div>
);
} else {
return <div>no dice</div>;
}
};
return checkRegister();
问题在于recursiveInjectProps()
无法注入register
并且errors
对于深度超过一层的子级(因此,包含在 div 中的名称字段)。我知道这一点,因为当它呈现时,我看到名称字段应该在哪里“没有骰子”。
非常感谢您对此的任何帮助。
解决方案
也许您应该使用上下文 API:https ://react-hook-form.com/api#useFormContext
import React from "react";
import { useForm, FormProvider, useFormContext } from "react-hook-form";
export default function App() {
const methods = useForm();
const onSubmit = data => console.log(data);
return (
<FormProvider {...methods} > // pass all methods into the context
<form onSubmit={methods.handleSubmit(onSubmit)}>
<NestedInput />
<input type="submit" />
</form>
</FormProvider>
);
}
function NestedInput() {
const { register } = useFormContext(); // retrieve all hook methods
return <input name="test" ref={register} />;
}
推荐阅读
- firebase - 使用唯一键时可关闭的小部件不会更改
- java - 初始化 VM 服务器时发生错误 VM 仅在 ARMv7+ VFP 上受支持
- c# - 如何获取 IMemoryCache 中键的 AbsoluteExpiration DateTimeOffset
- django - Django 'dict' 对象在使用 API 时没有属性 'META' 错误
- flutter - Flutter - 行中溢出时可拖动的文本
- python - 在 gem5 上运行 PARSEC 2.1
- docker - 带有 .net core 3.1 Web 应用程序的 docker 容器问题
- c - 错误:表达式不可分配(分配给 C 指针的一部分)
- c++ - (C++17; Boost) CMake 找不到请求的 Boost 库
- php - 未在 Dreamweaver CS6 中为 PHP 文件呈现实时视图