[英]react-hook-form stops working when put into a .map() - TypeError: Cannot read properties of undefined (reading 'ref')
Probably being stupid here but I'm struggling to get this working.可能在这里很愚蠢,但我正在努力让它发挥作用。 I'm trying to create a form based off an object.我正在尝试基于 object 创建一个表单。 Everything is fine when I'm not using a loop, but when I do, it stops working.当我不使用循环时一切都很好,但是当我这样做时,它停止工作。
Checkbox.tsx复选框.tsx
const Checkbox = React.forwardRef(
({ label, name, value, onChange, defaultChecked, ...rest }:any, forwardedRef:any) => {
const [checked, setChecked] = React.useState(defaultChecked);
React.useEffect(() => {
if (onChange) {
onChange(checked);
}
console.log(checked, 'checked')
console.log(name, 'name')
}, [checked]);
return (
<div onClick={() => setChecked(!checked)} style={{ cursor: "pointer" }}>
<input
style={{ display: "none" }}
ref={forwardedRef}
type="checkbox"
name={name}
value={value}
checked={checked}
onChange={e => {
setChecked(e.target.checked);
}}
/>
[{checked ? "X" : " "}]{label}
</div>
);
}
);
My Test() parent component:我的 Test() 父组件:
export default function Test() {
const onSubmit = (data:any) => {
alert(JSON.stringify(data));
};
const { handleSubmit, register, errors } = useForm();
return (
<div className="App">
<form onSubmit={handleSubmit(onSubmit)}>
<Checkbox
ref={register({ required: "This is required" })}
name="styles"
value={"tops"}
label=" tops"
/>
<Checkbox
ref={register({ required: "This is required" })}
name="styles"
value={"bottoms"}
label="bottoms"
/>
{errors.styles && <p className="error">{errors.styles.message}</p>}
<h2>Next section</h2>
<Checkbox
ref={register({ required: "Please select a colour" })}
name="colors"
value={"red"}
label=" Color (custom checkbox)"
/>
<Checkbox
ref={register({ required: "Please select a colour" })}
name="colors"
value={"blue"}
label=" Color (custom checkbox)"
/>
{errors.colors && <p className="error">{errors.colors.message}</p>}
<button type="submit">submit</button>
</form>
</div>
);
}
Everything works properly here, my data is structured as follows on submit:这里一切正常,我的数据在提交时的结构如下:
{"styles":["bottoms","tops"],"colors":["blue"]}
My problem arises when I try to build out the form from an object, like so:当我尝试从 object 构建表单时,出现了我的问题,如下所示:
'../content/formStyle' '../content/formStyle'
const girl = [
{
name: 'styles',
checkboxes: [
{
value: 'dresses',
label: 'Dresses',
},
{
value: 'pants',
label: 'Pants',
},
{
value: 'skirts',
label: 'Skirts',
},
{
value: 'shorts',
label: 'Shorts',
}
]
},
{
name: 'colors',
checkboxes: [
{
value: 'coral',
label: 'Coral'
},
{
value: 'lime',
label: 'Lime'
},
{
value: 'mint',
label: 'Mint'
},
{
value: 'raspberry',
label: 'Raspberry'
},
{
value: 'red',
label: 'Red'
},
{
value: 'purple',
label: 'Purple',
},
{
value: 'teal',
label: 'Teal'
},
{
value: 'blue',
label: 'Blue'
},
{
value: 'pink',
label: 'Pink'
}
]
}
]
export { girl }
And the component changes to:并且组件更改为:
import {girl} from '../content/formStyle'
export default function Test() {
const onSubmit = (data:any) => {
alert(JSON.stringify(data));
};
const { handleSubmit, register, errors } = useForm();
return (
<div className="App">
<form onSubmit={handleSubmit(onSubmit)}>
{girl?.map((section, index:any) =>{
return (
<>
<h2 className="font-bold">{section.name}</h2>
{section.checkboxes.map(checkbox => {
return (
<Checkbox
ref={register({ required: "This is required" })}
name={checkbox.value}
value={checkbox.value}
label={checkbox.label}
/>
)
})}
</>
)
})}
<button type="submit">submit</button>
</form>
</div>
);
}
Then I get the error:然后我得到错误:
react-hook-form.es.js?5302:429 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'ref')
at validateField (react-hook-form.es.js?5302:429:43)
at eval (react-hook-form.es.js?5302:1199:1)
What am I doing wrong?我究竟做错了什么?
Changing the register part of <Checkbox />
fixed it:更改<Checkbox />
的注册部分修复了它:
<Checkbox
key={index}
ref={register()}
name={checkbox.value}
value={true}
label={checkbox.label}
/>
I feel like react-hook-form
makes things much harder whereas you could write your own implementation of FormData
.我觉得react-hook-form
让事情变得更加困难,而您可以编写自己的FormData
实现。 I'm not able to explain why your code is not working, however I can propose an alternative explained easily here:我无法解释为什么您的代码不起作用,但是我可以在这里提出一个容易解释的替代方案:
import React, {useRef} from 'react';
function App() {
const form = useRef<HTMLFormElement>(null)
const submit = (e:any) => {
e.preventDefault();
const data = new FormData(form.current!);
const name = data.get("name");
console.log("name =", name);
}
return (
<form ref={form} onSubmit={submit}>
<label>
<input type="checkbox" name="name" />
<span>TRUC</span>
</label>
<button type="submit">Envoyer</button>
</form>
);
}
export default App;
Just like react-hook-form
the goal here is to avoid countless states controlling the inputs.就像react-hook-form
一样,这里的目标是避免无数状态控制输入。 The FormData object will collect the values and create an object according to the names. FormData object 将收集值并根据名称创建 object。
Note that 'on'
is used as value for a checkbox, not a boolean.请注意, 'on'
用作复选框的值,而不是 boolean。
NOTE : printing
data
in the console will show an empty object but the values are here.注意:控制台中的打印data
将显示一个空的 object 但值在这里。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.