在 6.X 中进行的重大 API 更改:
- 验证选项已更改为使用解析器函数包装器和不同的配置属性名称
注意:文档只是针对validationResolver->resolver 进行了修复,并且repo 中用于验证的代码示例尚未更新(仍validationSchema
用于测试)。感觉好像他们不确定要对那里的代码做什么,并且处于不确定状态。我会完全避免使用他们的 Controller 直到它稳定下来,或者使用 Controller 作为您自己的表单 Controller HOC 的薄包装器,这似乎是他们想要进入的方向。
查看官方沙盒演示和"false"
value 作为字符串的意外行为复选框供参考
import { yupResolver } from "@hookform/resolvers";
const { register, handleSubmit, control, getValues, setValue } = useForm({
resolver: yupResolver(schema),
defaultValues: Object.fromEntries(
boats.map((boat, i) => [
`boat_ids[${i}]`,
preselectedBoats.some(p => p.id === boats[i].id)
])
)
});
Controller
不再原生处理 Checkbox ( type="checkbox"
),或者更好地说,不正确地处理值。它不检测复选框的布尔值,并尝试将其转换为字符串值。你有几个选择:
- 不要使用
Controller
. 使用不受控制的输入
- 使用新
render
道具为您的复选框使用自定义渲染功能并添加 setValue 挂钩
- 像表单控制器 HOC 一样使用 Controller 并手动控制所有输入
避免使用控制器的示例:
https ://codesandbox.io/s/optimistic-paper-h39lq
https://codesandbox.io/s/silent-mountain-wdiov
与第一个原始示例相同,但使用了yupResolver
包装器
5.X 说明:
这是一个不需要 Controller 的简化示例。不受控制的是文档中的建议。仍然建议您为每个输入提供自己name
的数据并对数据进行转换/过滤以删除未检查的值,例如在后一个示例中使用 yup 和 validatorSchema,但就您的示例而言,使用相同的名称会导致值被添加到符合您要求的数组中。
https://codesandbox.io/s/practical-dijkstra-f1yox
无论如何,问题是defaultValues
您的复选框的结构不匹配。它应该是{[name]: boolean}
,其中names
生成的是文字字符串 boat_ids[${boat.id}]
,直到它通过不受控制的表单输入,这些输入将值捆绑到一个数组中。例如:form_input1[0] form_input1[1]
发出form_input1 == [value1, value2]
https://codesandbox.io/s/determined-paper-qb0lf
构建defaultValues: { "boat_ids[0]": false, "boat_ids[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, "")
});