我面临的问题与 React 如何处理状态更新和重新渲染有关。当您更改表单中某一字段(姓名、电子邮件或电话)的值时,所有三个输入组件都会重新呈现,因为它们都依赖于相同的 formData 状态。当状态改变时,React 会重新渲染整个组件,这就是为什么所有输入都会重新渲染,即使只有一个字段的值发生了变化。
在下面,如果更改名称的值,所有 3 个输入组件都将重新渲染。
const [formData, setFormData] = useState({ name: '', email: '', phone: '';
<FormInput
label="Name"
placeholder="Enter name"
id="name"
value={formData.name}
onChange={handleChange}
/>
<FormInput
label="Email"
placeholder="Enter email"
type='email'
id="email"
value={formData.email}
onChange={handleChange}
/>
<FormInput
label="Phone"
placeholder="Enter phone"
type='number'
id="phone"
value={formData.phone}
onChange={handleChange}
/>
表单输入.jsx
import { forwardRef} from "react";
import { cx } from "../../utils/helper";
export const commonInputCss = "w-full border border-neutral-300 rounded-xl p-4 outline-none text-text-700 placeholder:text-text-disabled bg-white disabled:bg-text-disabled disabled:cursor-not-allowed disabled:opacity-50 disabled:placeholder:text-main-black";
const FormInput = forwardRef(({
label, type = "text", id, inputCss, ...props
}, ref) => {
return (
<div className={cx("relative flex flex-col gap-y-1")}>
{label && (
<label htmlFor={id} className={cx(
"text-text-700 text-sm text-medium",
labelCss
)}>
{label}
</label>
)}
<input
type={type}
name={id}
id={id}
ref={ref}
{...props}
className={cx(
commonInputCss,
inputCss,
)}
/>
</div>
);
});
export default FormInput;
但是,我们需要重新渲染所有属性来更改一个属性值吗?
使用示例React Hook Form包
import React, { useState } from 'react';
import FormInput from '../../shared/forms/FormInput';
import { Controller, useForm } from 'react-hook-form';
const AddSellerModal = ({ isOpen, closeModal }) => {
const { control, handleSubmit, reset } = useForm({
defaultValues: { name: '', email: '', email: '', phone: '' }
});
return (
<>
<div className='my-10 space-y-5'>
<Controller
name="name"
control={control}
render={({ field }) => (
<FormInput
label="Shop Name"
placeholder="Enter shop name"
id="name"
{...field}
/>
)}
/>
<Controller
name="location"
control={control}
render={({ field }) => (
<FormInput
label="Location"
placeholder="Enter location"
id="location"
{...field}
/>
)}
/>
<Controller
name="email"
control={control}
render={({ field }) => (
<FormInput
label="Email"
placeholder="Enter email"
id="email"
type='email'
{...field}
/>
)}
/>
<Controller
name="phone"
control={control}
render={({ field }) => (
<FormInput
label="Phone"
placeholder="Enter phone"
id="phone"
type='number'
{...field}
/>
)}
/>
</div>
</CustomContainerModal>
</>
);
};
export default AddSellerModal;