Javascript 材料界面+;从挂钩和x2B起反应;多个复选框+;默认选中
我正在尝试使用Javascript 材料界面+;从挂钩和x2B起反应;多个复选框+;默认选中,javascript,forms,checkbox,material-ui,react-hook-form,Javascript,Forms,Checkbox,Material Ui,React Hook Form,我正在尝试使用react form hookMaterial UI构建一个包含多个“分组”复选框的表单 复选框是从HTTP请求异步创建的 我想提供一个对象ID数组作为默认值: defaultValues:{boat_id:trip?.boats.map(boat=>boat.id.toString())| |[]} 此外,当我选中或取消选中复选框时,我希望将对象的ID添加/删除到react hook form的值中 即(船号:[25,29,4]) 我怎样才能做到这一点 以下是我试图重现这个问题的
react form hook
Material UI
构建一个包含多个“分组”复选框的表单
复选框是从HTTP请求异步创建的
我想提供一个对象ID数组作为默认值:
defaultValues:{boat_id:trip?.boats.map(boat=>boat.id.toString())| |[]}
此外,当我选中或取消选中复选框时,我希望将对象的ID添加/删除到react hook form
的值中
即(船号:[25,29,4]
)
我怎样才能做到这一点
以下是我试图重现这个问题的一个例子
奖励点,使用Yup验证最小选中复选框
boat\u id:Yup.array().min(2“”)
打破6.X中的API更改:
- 验证选项已更改为使用解析程序函数包装和其他配置属性名称
注意:文档只是针对validationResolver->resolver进行了修复,repo中用于验证的代码示例尚未更新(仍然使用
进行测试)。感觉好像他们不确定他们想对那里的代码做什么,而且它处于一种不确定的状态。我会完全避免使用他们的控制器,直到它稳定下来,或者使用控制器作为您自己的表单控制器HOC的薄包装,这似乎是他们想要的方向。validationSchema
请参见将
值的意外行为作为复选框的字符串,以供参考“false”
不再以本机方式处理复选框(Controller
),或者更确切地说,不正确地处理值。它不会检测复选框的布尔值,并尝试将其转换为字符串值。您有几个选择:type=“Checkbox”
控制器
。使用非受控输入渲染
道具为复选框使用自定义渲染功能,并添加一个setValue挂钩与第一个原始示例相同,但使用
yupResolver
wrapper
5.X的说明: 下面是一个不需要控制器的简化示例。非受控是文件中的建议。仍然建议您为每个输入指定自己的
名称
,并对数据进行转换/筛选,以删除未检查的值,如后一示例中的yup和validatorSchema,但出于示例的目的,使用相同的名称会导致将值添加到符合您要求的数组中。无论如何,问题是您的
defaultValues
与复选框的结构不匹配。它应该是{[name]:boolean}
,其中生成的names
是文本字符串boat_id[${boat.id}]
,直到它通过将值聚集到一个数组中的非受控表单输入。例如:form\u input1[0]form\u input1[1]
发出form\u input1==[value1,value2]
生成默认值:{“boat_id[0]”:false,“boat_id[1]”:true…}
控制器需要布尔值来切换复选框值,并将其作为默认值提供给复选框
const { register, handleSubmit, control, getValues, setValue } = useForm({
validationSchema: schema,
defaultValues: Object.fromEntries(
preselectedBoats.map(boat => [`boat_ids[${boat.id}]`, true])
)
});
用于validationSchema的模式,用于验证至少选择了2个,并在将数据发送到onSubmit之前将数据转换为所需的模式。它过滤掉假值,因此您可以得到一个字符串ID数组:
const schema = Yup.object().shape({
boat_ids: Yup.array()
.transform(function(o, obj) {
return Object.keys(obj).filter(k => obj[k]);
})
.min(2, "")
});
以下是一个工作版本:
import React from "react";
import { useForm, Controller } from "react-hook-form";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import Checkbox from "@material-ui/core/Checkbox";
export default function CheckboxesGroup() {
const { control, handleSubmit } = useForm({
defaultValues: {
bill: "bill",
luo: ""
}
});
return (
<form onSubmit={handleSubmit(e => console.log(e))}>
{["bill", "luo"].map(name => (
<Controller
key={name}
name={name}
as={
<FormControlLabel
control={<Checkbox value={name} />}
label={name}
/>
}
valueName="checked"
type="checkbox"
onChange={([e]) => {
return e.target.checked ? e.target.value : "";
}}
control={control}
/>
))}
<button>Submit</button>
</form>
);
}
从“React”导入React;
从“react hook form”导入{useForm,Controller};
从“@material ui/core/FormControlLabel”导入FormControlLabel;
从“@material ui/core/Checkbox”导入复选框;
导出默认函数CheckboxesGroup(){
const{control,handleSubmit}=useForm({
默认值:{
比尔:“比尔”,
罗:""
}
});
返回(
console.log(e))}>
{[“比尔”,“罗”].map(名称=>(
{
返回e.target.checked?e.target.value:“”;
}}
control={control}
/>
))}
提交
);
}
代码沙盒链接:
但是,我不建议这样做,因为material UI中的复选框可能应该返回checked(布尔值)而不是(值)。我也一直在努力解决这个问题,以下是对我有效的方法 react hook form v6的更新解决方案,也可以在不使用
useState
的情况下完成(下面的沙盒链接):
import React,{useState}来自“React”;
从“react hook form”导入{useForm,Controller};
从“@material ui/core/FormControlLabel”导入FormControlLabel;
从“@material ui/core/Checkbox”导入复选框;
导出默认函数CheckboxesGroup(){
const defaultNames=[“bill”,“Manos”];
const{control,handleSubmit}=useForm({
默认值:{names:defaultNames}
});
常量[checkedValues,setCheckedValues]=useState(默认名称);
函数handleSelect(checkedName){
const newNames=checkedValues?包括(checkedName)
?checkedValues?.filter(名称=>name!==checkedName)
:[…(checkedValues??[]),checkedName];
setCheckedValues(新名称);
返回新名称;
}
返回(
console.log(数据))}>
{[“比尔”、“罗”、“马诺斯”、“用户120242”].地图(名称=>(
);
}}
control={control}
/>
}
键={name}
label={name}
/>
))}
提交
);
}
代码沙盒链接:
另一个包含默认选定项的解决方案不使用useState
:
这是我的解决方案,它不是在我的界面上使用Material UI cause中的所有默认组件
const schema = Yup.object().shape({
boat_ids: Yup.array()
.transform(function(o, obj) {
return Object.keys(obj).filter(k => obj[k]);
})
.min(2, "")
});
import React from "react";
import { useForm, Controller } from "react-hook-form";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import Checkbox from "@material-ui/core/Checkbox";
export default function CheckboxesGroup() {
const { control, handleSubmit } = useForm({
defaultValues: {
bill: "bill",
luo: ""
}
});
return (
<form onSubmit={handleSubmit(e => console.log(e))}>
{["bill", "luo"].map(name => (
<Controller
key={name}
name={name}
as={
<FormControlLabel
control={<Checkbox value={name} />}
label={name}
/>
}
valueName="checked"
type="checkbox"
onChange={([e]) => {
return e.target.checked ? e.target.value : "";
}}
control={control}
/>
))}
<button>Submit</button>
</form>
);
}