[英]Using object as a value in `react-hook-form`
I have a component that uses an object as a value.我有一个使用 object 作为值的组件。
I would like to use this component with react-hook-form
我想将此组件与
react-hook-form
一起使用
The problem is that react-hook-form
thinks that my object is a nested form control问题是
react-hook-form
认为我的 object 是一个嵌套的表单控件
This is just an example.这只是一个例子。
Range date picker is a common use case for such a behaviour范围日期选择器是此类行为的常见用例
The value that the component accepts:组件接受的值:
type ComponentValue = {
a: string;
b: string;
}
The component:组件:
const Component = ({ value, onChange }: { value: ComponentValue, onChange: (value: ComponentValue) => void }) => {
return (
<input value={value.a} onChange={e => onChange({ a: e.target.value, b: (Math.random() * 100 | 0).toString() }) } />
)
}
Form value表格值
type FormValues = {
someField: ComponentValue;
// other fields
};
Default values:默认值:
const defaultValues = {
someField: {
a: 'Default a',
b: 'Default b'
},
// other fields
};
useForm
usage: useForm
用法:
const {
register,
handleSubmit,
formState: { errors },
control,
} = useForm<FormValues>({
defaultValues,
});
Hovering over (or trying to use) errors
reveals the type:将鼠标悬停在(或尝试使用)
errors
上会显示类型:
const errors: {
someField?: {
a?: FieldError | undefined;
b?: FieldError | undefined;
} | undefined;
// other fields
}
But I would it to be:但我希望它是:
const errors: {
someField?: FieldError | undefined;
// other fields
}
Can I somehow force react-hook-form
to treat my object as a value instead of a nested form field?我可以以某种方式强制
react-hook-form
将我的 object 视为一个值而不是嵌套的表单字段吗?
If you want to combine 2 inputs in a same component, you can try the approach with a controller.如果您想在同一个组件中组合 2 个输入,您可以尝试使用 controller 的方法。
export default function App() {
const { control, handleSubmit, watch } = useForm({
defaultValues: {
travel: {
from: "paris",
to: "london"
}
}
});
const onSubmit = (data) => {
console.log("dans onSubmit", JSON.stringify(data, null, 2));
};
return (
<>
<h1>Travel</h1>
<form
onSubmit={handleSubmit(onSubmit)}
style={{ display: "flex", flexDirection: "column", maxWidth: 600 }}
noValidate
>
<TravelPicker control={control} />
<input type="submit" />
<pre>{JSON.stringify(watch(), null, 2)}</pre>
</form>
</>
);
The component have a control props, to be able to register the 2 inputs:该组件有一个控制道具,能够注册 2 个输入:
const TravelPicker = ({ control }) => {
return (
<>
<label>
From
<Controller
name="travel.from"
control={control}
render={({ field: { onChange, value, name } }) => (
<input name={name} value={value} onChange={(e) => onChange(e)} />
)}
/>
</label>
<label>
To
<Controller
name="travel.to"
control={control}
render={({ field: { onChange, value, name } }) => (
<input name={name} value={value} onChange={(e) => onChange(e)} />
)}
/>
</label>
</>
);
};
The errors object has then the same structure as the form inputs.错误 object 具有与表单输入相同的结构。
See this sandbox for a functional exemple.有关功能示例,请参阅此沙箱。
The createor of RHF seems to indicate here that you can also have only one component for 2 inputs. RHF 的创建者似乎在这里表明您也可以只有一个组件用于 2 个输入。
You can use setValue
and setError
like below:您可以像下面这样使用
setValue
和setError
:
const {setValue, setError} = useForm();
// ... some where in your form
<input
type = "text"
name = "from"
onChange = {
(event) => {
const value = event.target.value;
if(value === ""){
setError("from", "This field is required");
}else{
setValue(`from[0]`, {
"otherProperty" : "otherValue",
"from_value": value, // this is your input value
});
}
}
}
/>
Probably you would be iterating through an array.可能你会遍历一个数组。 change static 0 with your index in
setValue
If not you may use object syntax like below:用你在
setValue
中的索引改变 static 0如果不是你可以使用 object 语法如下:
//....
setValue(`from.your_property_name`, {
"otherProperty" : "otherValue",
"from_value": value, // this is your input value
});
// ....
This won't cause re-render of component.这不会导致重新渲染组件。
NOTE: Please be respectful when commenting.注意:评论时请尊重。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.