arrays - 从 ReactJS 中的数组中删除复杂组件
问题描述
我正在尝试制作组件列表。我需要单独删除这些项目,但似乎删除函数中的状态总是过时的。
例如,如果我添加 10 个作者并单击第 10 个作者删除按钮,它会显示 9 个元素(这已经是错误的),如果我单击第 2 个作者,它只会显示数组中的 1 个元素。我在这里错过了什么吗?
const [authorsFields, setAuthorsFields] = useState<Array<JSX.Element>>([]);
const removeAuthorField = () => {
console.log(authorsFields.length);
}
const removeButton = () => {
return (
<Col className={"d-flex justify-content-end py-1"}>
<Button variant={"danger"} onClick={() => removeAuthorField()}>Remove author</Button>
</Col>
);
}
const authorField = (removable: boolean) => {
return (
<>
<Row className={"mb-2"}>
<Form.Group className={"py-1"}>
<Form.Label>Author name</Form.Label>
<Form.Control type={"text"}/>
</Form.Group>
{removable && removeButton()}
</Row>
</>
);
}
const addAuthorField = () => {
if (authorsFields.length !== 0) {
setAuthorsFields((old) => [...old, authorField(true)]);
} else {
setAuthorsFields([authorField(false)]);
}
}
useEffect(() => {
if (authorsFields.length === 0) {
addAuthorField();
}
}, [])
return (
<>
<Col sm={3} style={{maxHeight: "60vh"}} className={"mt-4"}>
<Row>
{authorsFields}
<Row>
<Form.Group className={"py-1"}>
<Button style={{width: "100%"}} onClick={() => addAuthorField()}>
Add Author
</Button>
</Form.Group>
</Row>
</Row>
</Col>
</>
);
解决方案
使用以下功能组件作为示例,修改您的代码,了解如何使用与功能组件内部的状态管理分离的 JSX 元素。
import React, { useState } from "react";
import { Button, Row, Col } from "antd";
function App() {
const [authorsCount, setAuthorsCount] = useState(0);
// Use authorsFields to manage authors details in an array of objects
const [authorsFields, setAuthorsFields] = useState([]);
const removeAuthorField = (id) => {
// To remove relevant author filter out the authors without the relevant id
setAuthorsFields((old) =>
old.filter((authorField) => authorField.id !== id)
);
};
const addAuthorField = () => {
setAuthorsFields((old) => [...old, { id: authorsCount, removable: true }]);
setAuthorsCount((old) => old + 1);
};
return (
<div>
<Col sm={3} style={{ maxHeight: "60vh" }} className={"mt-4"}>
<Row>
{authorsFields.map((authorField) => (
<Row className={"mb-2"}>
<div className={"py-1"}>
<div>{`Author name ${authorField.id}`}</div>
</div>
{authorField.removable && (
<>
<Col className={"d-flex justify-content-end py-1"}>
<Button
variant={"danger"}
onClick={() => removeAuthorField(authorField.id)}
>
Remove author
</Button>
</Col>
</>
)}
</Row>
))}
<Row>
<div className={"py-1"}>
<Button
style={{ width: "100%" }}
onClick={() => addAuthorField()}
>
Add Author
</Button>
</div>
</Row>
</Row>
</Col>
</div>
);
}
export default App;
以下是观点。
推荐阅读
- react-native - 无论文本更改如何,如何读取 TextInput 上的每个按键
- amazon-web-services - AWS VPC 模块公有和私有子网 - Terraform
- c# - 我们可以使用带有字符串属性的 EnumDataType 属性来验证枚举值吗?
- form-data - FormData - 未捕获的 TypeError:无法构造“FormData”:参数 1 不是“HTMLFormElement”类型
- vim - 你能在 emacs 的邪恶模式下使用 vim 脚本和插件吗?邪恶模式的限制是什么?
- c - C:将字符串复制到字符串列表中
- javascript - 不使用下拉菜单访问对象,ngFor
- bots - Discord Bot- 使用 YAGPDB bot 的反应投票
- hadoop - 访问 kerberos Hive 的 java 操作(启用 SSL)
- c++ - 为什么这个对 sprintf_s() 的调用有效,我怎样才能在我的计算机上使它工作?