这是我的代码,
每当我单击
Add to list button
时,页面就会被重新渲染几次。
我知道这与反应钩子表单有关,因为如果我将按钮移到表单之外,它不会执行此操作。
我正在尝试调用
setBannersDataList
但这在反应钩子表单之外不起作用,仅适用于表单内的按钮。
有什么帮助吗?
'use client';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Button } from './ui/button';
import { SubmitHandler, UseFormRegister, UseFormReturn, UseFormSetValue, set, useForm } from 'react-hook-form';
import { Form, FormControl, FormField, FormItem, FormLabel } from './ui/form';
export default function Component({ details }: EditorProps) {
const [bannersDataList, setBannersDataList] = useState<any>([]);
const onSubmit: SubmitHandler<any> = (data) => console.log(data);
const form = useForm<any>();
const {
register,
setValue,
handleSubmit,
watch,
getValues,
formState: { errors },
} = form;
console.log('boo');
return (
<Form {...form}>
<form className="grid w-full items-start gap-6" onSubmit={handleSubmit(onSubmit)}>
<FormField
control={form.control}
name="size"
render={({ field }) => (
<FormItem>
<FormLabel>Sizes</FormLabel>
<FormControl>
<Select
{...field}
defaultValue="300x250"
>
<SelectTrigger id="size" className="items-start [&_[data-description]]:hidden">
<SelectValue placeholder="Select a size" />
</SelectTrigger>
<SelectContent>
{details.sizes?.map((size) => (
<SelectItem value={size} key={size}>
{size}
</SelectItem>
))}
</SelectContent>
</Select>
</FormControl>
</FormItem>
)}
/>
<Button
onClick={() => {
// click this causes the component to re-render loads of times even
// boo is consoled logged out like 20 times when I click this button
}}
>
Add banner to list
</Button>
</form>
</Form>
);
}
我期望的是,当我单击“将横幅添加到列表”按钮并调用 setBannersDataList 时,该组件不会重新渲染这么多次。
原因可能是单击按钮也会触发单击按钮时提交表单的默认行为。这就是为什么当您将按钮移到表单之外时它不会重新呈现表单。
您可以实现的另一种方法是在 onClick 回调中添加一行(
e.preventDefault()
),这是按钮的代码,同时将其保留在表单中,
<Button
onClick={(e) => {
e.preventDefault(); // new line added
// your further logic
}}
>
Add banner to list
</Button>
您面临的问题似乎与表单内按钮的
onClick
事件触发的组件重新渲染有关。此行为可能是由 React Hook Form 和组件状态更新之间的交互引起的。一种可能的解决方案是防止按钮的 onClick
事件的默认行为,这可能导致表单提交并触发重新渲染。您可以通过在 event.preventDefault()
处理程序中调用 onClick
来实现此目的。以下是修改按钮的 onClick
处理程序的方法:
<Button
onClick={(event) => {
event.preventDefault(); // Prevent default form submission
// Your logic here
}}
>
Add banner to list
</Button>