从 ReactJS 中的数组中删除复杂组件

Posted

技术标签:

【中文标题】从 ReactJS 中的数组中删除复杂组件【英文标题】:Removing complex components from an array in ReactJS 【发布时间】:2021-10-17 15:01:11 【问题描述】:

我正在尝试制作组件列表。我需要单独删除项目,但删除函数中的状态似乎总是过时的。

例如,如果我添加 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 元素保留在 render 方法中而不是使用 state ?您可以使用 array.map() 在功能组件的 return 内创建一个 authorField 元素数组。 @K.vindi 好吧,我需要动态添加和删除,所以我想象在这种情况下我需要使用状态。我错了吗? 是的,最好将所有 JSX 元素移动到返回中。要添加和删除 authorField,您需要管理一个包含这些作者作为对象数组的状态。每个对象都可以包含与作者相关的细节。为了添加用户详细信息,您还可以更好地管理表单输入。并且不要在其中保留 JSX 元素。使用下面的code-sn-p,我已经举个例子了。 【参考方案1】:

以下面的功能组件为例,修改你的代码如何使用与功能组件内部的状态管理分开的 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;

下面是视图。

【讨论】:

谢谢你,效果很好。你介意解释一下我做错了什么吗?

以上是关于从 ReactJS 中的数组中删除复杂组件的主要内容,如果未能解决你的问题,请参考以下文章

单击事件后如何从 ReactJS 中的数组中删除对象

reactjs - 状态更改后组件不呈现[重复]

在reactjs中删除重复项后如何从状态值和setstate创建数组

如何从 Reactjs 中的 useEffect 挂钩访问道具

如何从 ReactJS 组件调用 Laravel Api 路由?

当从数组呈现ReactJS组件时,组件的onChange函数将传递最后一个参数值