<StarRatingInput
rating={rating}
setRating={(newValue: string) => {
setRating(newValue);
(
document.getElementById("rating") as HTMLInputElement
).value = newValue;
console.log("new", newValue);
}}
/>
<input hidden id="rating" type="text" {...register("rating")}/>
在上面的代码中,StarRatingInput 是一个组件,它并不是真正的输入元素,而是被用作一个输入元素。由于我无法在该组件内注册挂钩表单,因此我在其下方创建了一个新的隐藏
input
标签,尝试注册它。根据上面的代码,当 rating
状态改变时,input
标签的值也会改变。但我无法对 rating
执行验证。
我的评级验证如下
rating: z.string().refine(
(value: string) => {
console.log(value);
const ratings = ["1", "2", "3", "4", "5"];
return ratings.includes(value);
},
{ message: "Please select valid rating stars" },
),
问题在于,精炼回调函数内的值始终为空字符串。 我可以确认
input
标签的值正在变化,但无论怎样 value
参数始终为空字符串。
我还尝试将
input
标签更改为受控组件,但它也不起作用<input value={rating} id="rating" type="text" {...register("rating")}/>
StarRatingInput.tsx 的实现
function StarRatingInput({
rating,
setRating,
}: {
rating: string;
setRating: (newValue: string) => void;
}) {
return (
<div>
{[1, 2, 3, 4, 5].map((star) => {
return (
<span
key={star}
className="start"
style={{
cursor: "pointer",
color: parseInt(rating) >= star ? "gold" : "gray",
fontSize: `35px`,
}}
onClick={() => {
setRating(star.toString());
}}
>
{" "}
★{" "}
</span>
);
})}
</div>
);
}
export default StarRatingInput;
不建议采用这种方法。你几乎永远不会想直接改变react中的DOM。
React hook 表单提供了与非
<input>
元素交互的其他方式。
即
getValues
和 setValue
函数。
例如:
const { getValues, setValue, watch, register } = useForm({
defaultValues: { name: '', isCool: false }
})
现在您可以访问
isCool
表单状态来呈现该值:
{ getValues('isCool') ? 'Cool' : 'Not Cool' }
并且可以通过调用
setValue
来设置:
<button onClick={() => setValue('isCool', true)}>Cool</button>
<button onClick={() => setValue('isCool', false)}>Not Cool</button>
但一个问题是,反应钩子表单假设表单状态值不需要重新渲染页面。因此,添加对
watch
的调用会告诉它监视该字段上的更改并重新渲染。
useEffect(() => {
watch('isCool') // Ensures a re-render when `isCool` is changed.
}, [])
请参阅游乐场,其中包含类型安全但不可运行的示例。