React Hook 表单 + Material UI 复选框
React Hook Forms + Material UI Checkboxes
我在使用 React Hook 表单和 material-ui 复选框组件提交表单 build 时遇到错误。复选框的数量是 build 来自我的列表 api:
<Grid item xs={12}>
<FormControl
required
error={errors.project?.stack ? true : false}
component='fieldset'>
<FormLabel component='legend'>Tech Stack</FormLabel>
<FormGroup>
<Grid container spacing={1}>
{techs.map((option, i) => (
<Grid item xs={4} key={i}>
<FormControlLabel
control={
<Checkbox
id={`stack${i}`}
name='project.stack'
value={option.id}
inputRef={register({required: 'Select project Tech Stack'})}
/>
}
label={option.name}
/>
</Grid>
))}
</Grid>
</FormGroup>
<FormHelperText>{errors.project?.stack}</FormHelperText>
</FormControl>
</Grid>
提交表单时出现以下错误(几次,每个复选框呈现 1 个):
Uncaught (in promise) Error: Objects are not valid as a React child
(found: object with keys {type, message, ref}). If you meant to render
a collection of children, use an array instead.
我不明白这个错误。该消息显然表明这是一个呈现问题,但组件呈现正常。问题发生在提交上。有什么建议吗?
谢谢
我设法在不使用 Controller 的情况下使其工作。
道具应该在 FormControlLabel 内而不是在 Checkbox
内
<Grid item xs={4} key={i}>
<FormControlLabel
value={option.id}
control={<Checkbox />}
label={option.name}
name={`techStack[${option.id}]`}
inputRef={register}
/>
</Grid>
))}
UPDATE: 如果你使用 RHF >= 7,你应该使用 props.field
调用 props.field.value
和 props.field.onChange
.
您可以使用默认的复选框控制器:
<FormControlLabel
control={
<Controller
name={name}
control={control}
render={(props) => (
<Checkbox
{...props}
checked={props.value}
onChange={(e) => props.onChange(e.target.checked)}
/>
)}
/>
}
label={label}
/>
我使用了 RHF 的控制器示例,但必须添加 checked={props.value}
:
https://github.com/react-hook-form/react-hook-form/blob/master/app/src/controller.tsx
任何一个例子都有效,我正在使用这个:
const checboxArray = [{
name: '1h',
label: '1 hora'
},
{
name: '12h',
label: '12 horas'
},
{
name: '24h',
label: '24 horas'
},
{
name: '3d',
label: '3 dias'
},
];
//This inside render function:
{
checboxArray.map((checboxItem) => (
<Controller name = {
checboxItem.name
}
control = {
control
}
key = {
checboxItem.name
}
rules = {
{
required: true
}
}
render = {
({
field: {
onChange,
value
}
}) =>
<
FormControlLabel
control = { <Checkbox
checked = {!!value
}
onChange = {
(event, item) => {
onChange(item);
}
}
name = {
checboxItem.name
}
color = "primary" /
>
}
label = {
checboxItem.label
}
/>
}
/>
))
}
如果有人难以通过 React material-ui 和 react-hook-form 实现多选复选框,您可以查看我的 codesandbox example
另外,react-hook-form 在其文档 useController
章节下提供了 code example(不要忘记切换到复选框选项卡)。
Material UI + React Hook Form + 是的 。
示例页面:
https://moiseshp.github.io/landing-forms/
- 没有额外的依赖
- 显示和隐藏错误消息
// import { yupResolver } from '@hookform/resolvers/yup'
// import * as yup from 'yup'
const allTopics = [
'React JS',
'Vue JS',
'Angular'
]
const defaultValues = {
topics: []
}
const validationScheme = yup.object({
topics: yup.array().min(1),
})
const MyForm = () => {
const resolver = yupResolver(validationScheme)
const {
control,
formState: { errors },
handleSubmit
} = useForm({
mode: 'onChange',
defaultValues,
resolver
})
const customSubmit = (data) => alert(JSON.stringify(data))
return (
<form onSubmit={handleSubmit(customSubmit)}>
<FormControl component="fieldset" error={!!errors?.topics}>
<FormLabel component="legend">Topics</FormLabel>
<FormGroup row>
<Controller
name="topics"
control={control}
render={({ field }) => (
allTopics.map(item => (
<FormControlLabel
{...field}
key={item}
label={item}
control={(
<Checkbox
onChange={() => {
if (!field.value.includes(item)) {
field.onChange([...field.value, item])
return
}
const newTopics = field.value.filter(topic => topic !== item)
field.onChange(newTopics)
}}
/>
)}
/>
))
)}
/>
</FormGroup>
<FormHelperText>{errors?.topics?.message}</FormHelperText>
</FormControl>
</form>
)
}
export default MyForm
我在使用 React Hook 表单和 material-ui 复选框组件提交表单 build 时遇到错误。复选框的数量是 build 来自我的列表 api:
<Grid item xs={12}>
<FormControl
required
error={errors.project?.stack ? true : false}
component='fieldset'>
<FormLabel component='legend'>Tech Stack</FormLabel>
<FormGroup>
<Grid container spacing={1}>
{techs.map((option, i) => (
<Grid item xs={4} key={i}>
<FormControlLabel
control={
<Checkbox
id={`stack${i}`}
name='project.stack'
value={option.id}
inputRef={register({required: 'Select project Tech Stack'})}
/>
}
label={option.name}
/>
</Grid>
))}
</Grid>
</FormGroup>
<FormHelperText>{errors.project?.stack}</FormHelperText>
</FormControl>
</Grid>
提交表单时出现以下错误(几次,每个复选框呈现 1 个):
Uncaught (in promise) Error: Objects are not valid as a React child (found: object with keys {type, message, ref}). If you meant to render a collection of children, use an array instead.
我不明白这个错误。该消息显然表明这是一个呈现问题,但组件呈现正常。问题发生在提交上。有什么建议吗?
谢谢
我设法在不使用 Controller 的情况下使其工作。 道具应该在 FormControlLabel 内而不是在 Checkbox
内 <Grid item xs={4} key={i}>
<FormControlLabel
value={option.id}
control={<Checkbox />}
label={option.name}
name={`techStack[${option.id}]`}
inputRef={register}
/>
</Grid>
))}
UPDATE: 如果你使用 RHF >= 7,你应该使用 props.field
调用 props.field.value
和 props.field.onChange
.
您可以使用默认的复选框控制器:
<FormControlLabel
control={
<Controller
name={name}
control={control}
render={(props) => (
<Checkbox
{...props}
checked={props.value}
onChange={(e) => props.onChange(e.target.checked)}
/>
)}
/>
}
label={label}
/>
我使用了 RHF 的控制器示例,但必须添加 checked={props.value}
:
https://github.com/react-hook-form/react-hook-form/blob/master/app/src/controller.tsx
任何一个例子都有效,我正在使用这个:
const checboxArray = [{
name: '1h',
label: '1 hora'
},
{
name: '12h',
label: '12 horas'
},
{
name: '24h',
label: '24 horas'
},
{
name: '3d',
label: '3 dias'
},
];
//This inside render function:
{
checboxArray.map((checboxItem) => (
<Controller name = {
checboxItem.name
}
control = {
control
}
key = {
checboxItem.name
}
rules = {
{
required: true
}
}
render = {
({
field: {
onChange,
value
}
}) =>
<
FormControlLabel
control = { <Checkbox
checked = {!!value
}
onChange = {
(event, item) => {
onChange(item);
}
}
name = {
checboxItem.name
}
color = "primary" /
>
}
label = {
checboxItem.label
}
/>
}
/>
))
}
如果有人难以通过 React material-ui 和 react-hook-form 实现多选复选框,您可以查看我的 codesandbox example
另外,react-hook-form 在其文档 useController
章节下提供了 code example(不要忘记切换到复选框选项卡)。
Material UI + React Hook Form + 是的 。 示例页面: https://moiseshp.github.io/landing-forms/
- 没有额外的依赖
- 显示和隐藏错误消息
// import { yupResolver } from '@hookform/resolvers/yup'
// import * as yup from 'yup'
const allTopics = [
'React JS',
'Vue JS',
'Angular'
]
const defaultValues = {
topics: []
}
const validationScheme = yup.object({
topics: yup.array().min(1),
})
const MyForm = () => {
const resolver = yupResolver(validationScheme)
const {
control,
formState: { errors },
handleSubmit
} = useForm({
mode: 'onChange',
defaultValues,
resolver
})
const customSubmit = (data) => alert(JSON.stringify(data))
return (
<form onSubmit={handleSubmit(customSubmit)}>
<FormControl component="fieldset" error={!!errors?.topics}>
<FormLabel component="legend">Topics</FormLabel>
<FormGroup row>
<Controller
name="topics"
control={control}
render={({ field }) => (
allTopics.map(item => (
<FormControlLabel
{...field}
key={item}
label={item}
control={(
<Checkbox
onChange={() => {
if (!field.value.includes(item)) {
field.onChange([...field.value, item])
return
}
const newTopics = field.value.filter(topic => topic !== item)
field.onChange(newTopics)
}}
/>
)}
/>
))
)}
/>
</FormGroup>
<FormHelperText>{errors?.topics?.message}</FormHelperText>
</FormControl>
</form>
)
}
export default MyForm