javascript - 反应多个输入字段 onChange 不起作用
问题描述
如果用户单击添加输入按钮并将这些值存储为对象,我正在尝试添加一个额外的输入字段:
const {useState } = React;
const InviteUser = () => {
const [userDetails, setUserDetails] = useState([
{
email: "",
role: ""
}
]);
const handleCancel = () => {
setUserDetails([
{
email: "",
role: ""
}
]);
};
const handleChange = (e, index) => {
const { name, value } = e.target;
let newUserDetails = [...userDetails];
newUserDetails[index] = { ...userDetails[index], [name]: value };
setUserDetails({ newUserDetails });
};
const addInput = () => {
setUserDetails([...userDetails, { email: "", role: "" }]);
};
return (
userDetails.length >= 0 && (
<div>
{[...userDetails].map((el, index) => (
<form key={index + el} name={el}>
<div>
<input
type="email"
name="email"
required
onChange={(event) => handleChange(event, index)}
value={el.email}
style={{ marginTop: 17 }}
placeholder="Enter Email Address"
/>
</div>
<div>
<input
type="text"
name="roles"
required
value={el.role}
style={{ marginTop: 17 }}
placeholder="Role"
onChange={(event) => handleChange(event, index)}
/>
</div>
</form>
))}
<div>
<button label="Invite Another?" onClick={addInput}>
Add input
</button>
</div>
<div>
<button>Invite</button>
<button onClick={() => handleCancel()}>Cancel</button>
</div>
</div>
)
);
};
ReactDOM.render(
<InviteUser/>,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>
状态是包含电子邮件和角色的对象数组:
const [userDetails, setUserDetails] = useState([
{
email: "",
role: ""
}
]);
handleChange 函数,它通过将一个对象(用户从每一行输入的值)推入一个数组来更新状态:
const handleChange = (e, index) => {
const { name, value } = e.target;
let newUserDetails = [...userDetails];
newUserDetails[index] = { ...userDetails[index], [name]: value };
setUserDetails({ newUserDetails });
};
和 addInput 函数添加新的输入字段行:
const addInput = () => {
setUserDetails([...userDetails, { email: "", role: "" }]);
};
并返回 JSX:
return (
userDetails.length >= 0 && (
<InputsContainer>
{[...userDetails].map((el, index) => (
<form key={index + el} name={el} onSubmit={handleSubmit}>
<EmailContainer>
<input
type="email"
name="email"
required
onChange={(event) => handleChange(event, index)}
value={el.email}
style={{ marginTop: 17 }}
placeholder="Enter Email Address"
/>
</EmailContainer>
<RolesContainer>
<input
type="text"
name="roles"
required
value={el.role}
style={{ marginTop: 17 }}
placeholder="Role"
onChange={(event) => handleChange(event, index)}
/>
</RolesContainer>
</form>
))}
<InviteButtonContainer>
<button label="Invite Another?" onClick={addInput}>
Add input
</button>
</InviteButtonContainer>
<SubmitButtonsContainer>
<button onClick={(event) => handleSubmit(event)}>Invite</button>
<button onClick={() => handleCancel()}>Cancel</button>
</SubmitButtonsContainer>
</InputsContainer>
)
);
我在这里做错了什么?
解决方案
你有两个问题:
- 在
setUserDetails
您返回包装在对象中的数组时,而不是仅仅返回数组。 - 在角色字段中,您从
el.role
insted 中获取值el.roles
。
此外,由于您更新当前状态,基于之前的状态,最好使用功能更新。
const {useState } = React;
const createNewEntry = () => ({ email: "", role: "" });
const InviteUser = () => {
const [userDetails, setUserDetails] = useState(() => [createNewEntry()]);
const handleCancel = () => {
setUserDetails([createNewEntry()]);
};
const handleChange = (e, index) => {
const { name, value } = e.target;
setUserDetails(userDetails => {
const newUserDetails = [...userDetails];
newUserDetails[index] = { ...userDetails[index], [name]: value };
return newUserDetails;
});
};
const addInput = () => {
setUserDetails([...userDetails, createNewEntry()]);
};
return (
userDetails.length >= 0 && (
<div>
{[...userDetails].map((el, index) => (
<form key={index + el} name={el}>
<div>
<input
type="email"
name="email"
required
onChange={(event) => handleChange(event, index)}
value={el.email}
style={{ marginTop: 17 }}
placeholder="Enter Email Address"
/>
</div>
<div>
<input
type="text"
name="roles"
required
value={el.roles}
style={{ marginTop: 17 }}
placeholder="Role"
onChange={(event) => handleChange(event, index)}
/>
</div>
</form>
))}
<div>
<button label="Invite Another?" onClick={addInput}>
Add input
</button>
</div>
<div>
<button>Invite</button>
<button onClick={() => handleCancel()}>Cancel</button>
</div>
</div>
)
);
};
ReactDOM.render(
<InviteUser/>,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>
推荐阅读
- html - 加密的 R Markdown HTML 文件不显示图表?
- javascript - 在 *ngIf 指令中:如何将函数的返回值存储在变量中并在同一个 *ngIf 中使用它?
- python - python vtk 8.2.0 似乎有损坏的属性
- algorithm - 为给定查询计算树中边任一侧的节点数
- c# - C# OpenQA.Selenium.WebDriverException:“未知错误:无法创建 Chrome 进程。”
- python - MeanShift 或带宽估计器花费太长时间来聚类图像点
- azure-devops - 如何在 Azure Devops 中从同一组织内的不同项目下载工件?
- flutter - 如何解决“等待设备上 Flutter 的连接...”
- python - 如何使用opencv python绘制热图的轮廓并叠加在原始图像上?
- xpath - For循环没有刮掉所有项目,只有一个