我想要实现的是,将每个输入创建为自己的组件。当我按任意键时,我的应用一直在重新渲染,我不知道如何修复。我知道我是否会使用controlledInputs ->所以每个输入都有自己的可用useState。但是这样做的主要思想是
import React, { useState } from 'react';
const ControlledInputs = () => {
const [person, setPerson] = useState({ firstName: '', email: '', age: '' });
const [people, setPeople] = useState([]);
const handleChange = (e) => {
const name = e.target.name;
const value = e.target.value;
setPerson({ ...person, [name]: value });
};
const handleSubmit = (e) => {
e.preventDefault();
if (person.firstName && person.email && person.age) {
const newPerson = { ...person, id: new Date().getTime().toString() };
setPeople([...people, newPerson]);
setPerson({ firstName: '', email: '', age: '' });
}
};
function FormControl({number, idname , type , text}){
return(
<div className='form-control'>
<label htmlFor={idname}>{text} : </label>
<input
type={type}
id={idname}
name={idname}
value={person[idname]}
onChange={(e) =>handleChange(e)}
/>
</div>
)
}
return (
<>
<article className='form'>
<form>
<FormControl idname={"firstName"} type={"text"} text={"First name"}/>
<FormControl type={"email"} idname={"email"} text={"Email"}/>
<FormControl type={"age"} idname={"age"} text={"Age"}/>
<button type='submit' className='btn' onClick={handleSubmit}>
add person
</button>
</form>
</article>
<article>
{people.map((person) => {
const { id, firstName, email, age } = person;
return (
<div key={id} className='item'>
<h4>{firstName}</h4>
<p>{email}</p>
<p>{age}</p>
</div>
);
})}
</article>
</>
);
};
export default ControlledInputs;
您需要在ControlledInputs
之外定义FormControl
,否则,React将重新创建它,您将失去焦点和数据。
需要在FormControl
中传递value
和handleChange
作为道具。
这里是你可以重构的代码。请注意,您定义的number
没有被删除。
function FormControl({value, handleChange, idname , type , text}){
return(
<div className='form-control'>
<label htmlFor={idname}>{text} : </label>
<input
type={type}
id={idname}
name={idname}
value={value}
onChange={(e) =>handleChange(e)}
/>
</div>
)
}
在form
中的用法:
function FormControl({value, handleChange, idname , type , text}){
return(
<div className='form-control'>
<label htmlFor={idname}>{text} : </label>
<input
type={type}
id={idname}
name={idname}
value={value}
onChange={(e) =>handleChange(e)}
/>
</div>
)
}
const ControlledInputs = () => {
const [person, setPerson] = useState({ firstName: '', email: '', age: '' });
const [people, setPeople] = useState([]);
const handleChange = (e) => {
const name = e.target.name;
const value = e.target.value;
setPerson({ ...person, [name]: value });
};
const handleSubmit = (e) => {
e.preventDefault();
if (person.firstName && person.email && person.age) {
const newPerson = { ...person, id: new Date().getTime().toString() };
setPeople([...people, newPerson]);
setPerson({ firstName: '', email: '', age: '' });
}
};
return (
<>
<article className='form'>
<form>
<FormControl idname={"firstName"} type={"text"} text={"First name"} value={person['firstName']} handleChange={handleChange}/>
<FormControl type={"email"} idname={"email"} text={"Email"} value={person['email']} handleChange={handleChange}/>
<FormControl type={"age"} idname={"age"} text={"Age"} value={person['age']} handleChange={handleChange}/>
<button type='submit' className='btn' onClick={handleSubmit}>
add person
</button>
</form>
</article>
<article>
{people.map((person) => {
const { id, firstName, email, age } = person;
return (
<div key={id} className='item'>
<h4>{firstName}</h4>
<p>{email}</p>
<p>{age}</p>
</div>
);
})}
</article>
</>
);
};
这是因为FormControl
是在ControlledInputs
组件内部定义的。因此,在ControlledInputs
的每个渲染上,您都创建了一个新的FormControl
函数,这意味着React将把它视为与之前渲染中的一个不同的组件,因此它将失去焦点,因为旧的被认为是未安装的。
只需在另一个之外定义FormControl
,并将您需要的额外数据作为道具传递给它,然后您应该设置。