如何让React MUI的Rating组件成为表单必填项?
解决MUI Rating组件必填校验问题及原因说明
问题解决方法
你之前的代码依赖原生input的required属性但未生效,核心原因是react-hook-form的校验逻辑需要和表单库的规则绑定,而非依赖原生表单属性。下面提供两种可行方案:
方案1:结合隐藏input与react-hook-form校验规则
import React, { useState, useEffect } from "react"; import Button from "@material-ui/core/Button"; import FormControlLabel from "@material-ui/core/FormControlLabel"; import Container from "@material-ui/core/Container"; import { useForm, formState: { errors } } from "react-hook-form"; import Rating from "@material-ui/lab/Rating"; import Typography from "@material-ui/core/Typography"; export default function Create() { const [rating, setRating] = useState(null); const { register, handleSubmit, setValue } = useForm(); // 同步Rating选中值到表单库状态 useEffect(() => { setValue("rating", rating); }, [rating, setValue]); const onSubmit = (data) => { console.log(data); }; return ( <Container component="main" maxWidth="xs"> <div> <form onSubmit={handleSubmit(onSubmit)}> <FormControlLabel required control={ <Rating name="rating" value={rating} precision={1} onChange={(_, value) => setRating(value)} /> } label="请评分" /> {/* 显示校验错误提示 */} {errors.rating && ( <Typography color="error" variant="body2"> {errors.rating.message} </Typography> )} {/* 注册字段并设置校验规则 */} <input type="hidden" {...register("rating", { required: "请选择评分", min: { value: 1, message: "评分不能低于1分" } })} /> <Button type="submit" fullWidth variant="contained" color="primary"> Submit </Button> </form> </div> </Container> ); }
方案2:使用react-hook-form的Controller组件(更推荐)
用Controller直接包裹Rating组件,无需手动同步状态,表单库会自动管理值与校验:
import React from "react"; import Button from "@material-ui/core/Button"; import FormControlLabel from "@material-ui/core/FormControlLabel"; import Container from "@material-ui/core/Container"; import { useForm, Controller, formState: { errors } } from "react-hook-form"; import Rating from "@material-ui/lab/Rating"; import Typography from "@material-ui/core/Typography"; export default function Create() { const { control, handleSubmit } = useForm(); const onSubmit = (data) => { console.log(data); }; return ( <Container component="main" maxWidth="xs"> <div> <form onSubmit={handleSubmit(onSubmit)}> <Controller name="rating" control={control} rules={{ required: "请选择评分", min: { value: 1, message: "评分不能低于1分" } }} render={({ field }) => ( <FormControlLabel required control={ <Rating {...field} precision={1} value={field.value ?? null} onChange={(_, value) => field.onChange(value)} /> } label="请评分" /> )} /> {errors.rating && ( <Typography color="error" variant="body2"> {errors.rating.message} </Typography> )} <Button type="submit" fullWidth variant="contained" color="primary"> Submit </Button> </form> </div> </Container> ); }
为什么Rating组件没有required属性?
- Rating是MUI封装的纯UI组件,不属于原生HTML表单元素(如input、select),原生
required属性仅对原生表单控件生效。 - Rating的核心作用是渲染星级选择界面,没有内置表单校验逻辑,这类自定义组件的必填校验需要结合react-hook-form、Formik等表单库,或者手动实现校验逻辑。
内容的提问来源于stack exchange,提问作者Yonlif
相关产品推荐
相关产品推荐

