首页 > 解决方案 > 从 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>
        </>
    );

标签: arraysreactjscomponents

解决方案


使用以下功能组件作为示例,修改您的代码,了解如何使用与功能组件内部的状态管理分离的 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;

以下是观点。

在此处输入图像描述


推荐阅读