首页 > 解决方案 > (反应)从数组中删除元素

问题描述

希望你一切都好。我已经环顾了很长时间,但无法找到解决我遇到的这个问题的方法。我遇到的问题是我无法从显示的数组中删除项目。我无法删除它的原因是,一旦元素显示在子组件中,然后又被带回父组件,它就不再具有与进入子组件时相同的形状。它以数组的形式进入子组件,并以对象的形式从子组件中出来,并具有额外的复杂层。有人可以帮助我理解为什么该对象(盯着看)正在改变其形状,以及如何将其形状保留为数组,然后从中删除元素?

当它返回父组件时,我无法将数组保留为数组。

我查看了许多资源,但无法弄清楚。我正在尝试从数组中删除一个对象,以便将其从实时反应中删除。问题是,当 prevState.mapped(object) 从渲染数组中每个对象的单个卡片的组件返回时,它没有被识别为数组。我相信这与formik有关。我尝试了以下方法:

我已经环顾了一下,但我一定不是在问正确的问题,因为我没有得到关于为什么我正在使用的 prevState 对象一旦返回到父对象就不是数组的答案零件。我不怀疑这个问题的解决方案相当简单。我已经粘贴了以下相关代码:它按照运行的顺序粘贴:

1.) 这部分代码进行 AXIOS 调用,当调用成功时,该数据将被过滤到卡片组件中。

class Organizations extends Component {
  constructor(props) {
    super(props);
    this.state = { organizations: [], mappedOrgs: [] };
  }

  //ORG LOAD
  componentDidMount() {
    paginatedList(0, 8).then(this.onOrgSuccess);
  }

  //ORG CALL SUCCESS

  onOrgSuccess = (config) => {
    let organizations = config.item.pagedItems;
    this.setState((prevState) => {
      return {
        ...prevState,
        mappedOrgs: organizations.map(this.mapOrg),
      };
    }, this.stateChanged);
  };

  mapOrg = (Organization) => (
    _logger(Organization, "ORGANIZATION, ORGANIZATION"),
    (
      <OrgCard
        Organization={Organization}
        key={Organization.id}
        editOrganization={this.editOrganization}
        deleteFunction={this.deleteFunction}
      />
    )
  );

2.) 以下是卡片组件中的功能。'Handle Delete' 功能也确实通过了组件,因此,我也描述了它。它显然是整体呈现的组件的一部分。

const OrgCard = ({ Organization, editOrganization, deleteFunction }) => {
  //OPERATIONAL FUNCTIONS
  _logger(Organization);

  //DELETE
  const OrgDelete = () => {
    deleteOrg(Organization.id).then(deleteSuccess).catch(deleteToastFail);
  };

  //SUCCESS FUNCTIONS

  const deleteSuccess = () => {
    deleteFunction(Organization);
  };

    <Button
      onClick={OrgDelete}
      className="btn-danger btn-lg center"
      align="center"
    >
      Delete
    </Button>

下面是应该从数组中删除的函数。这是您在上面看到的父组件,并且与编号为“1”的代码主体位于同一代码主体中。有问题的代码周围有两颗星,实际代码中显然没有两颗星。

  deleteFunction = (deletedOrg) => {
    this.setState((prevState) => {
      const indexOfOrg = **prevState.mappedOrgs**.findIndex(
        (Org) => Org.id === deletedOrg.id
      );
      let updatedOrgs = [...prevState.mappedOrgs];
      if (indexOfOrg >= 0) {
        updatedOrgs.slice(indexOfOrg, 1);
      }
      _logger(updatedOrgs);

      return { mappedOrgs: updatedOrgs };
    }, this.stateChanged);
  };

我不太了解 Formik 和 props 验证,所以我将在下面发布它,以防它有一些相关性。

这是编号为“1”的代码正文中的道具验证

Organizations.propTypes = {
  history: PropTypes.shape({
    push: PropTypes.func,
  }),
  findIndex: PropTypes.func,
  deleteFunction: PropTypes.checkPropTypes({
    deletedOrg: PropTypes.number,
    mappedOrgs: PropTypes.array,
    findIndex: PropTypes.func,
    updatedOrgs: PropTypes.array,
    splice: PropTypes.func,
    indexOfOrg: PropTypes.number,
  }),
};

我一直在尝试很多东西,我什至在卡片渲染中也进行了道具验证。在这种情况下,这是在“2”中。

OrgCard.propTypes = {
  Organization: PropTypes.shape({
    id: PropTypes.number,
    OrganizationTypeId: PropTypes.number,
    name: PropTypes.string,
    description: PropTypes.string,
    logo: PropTypes.string,
    locationId: PropTypes.number,
    phone: PropTypes.string,
    siteUrl: PropTypes.string,
  }).isRequired,
  deleteOrg: PropTypes.func,
  deleteFunction: PropTypes.func,
  editOrganization: PropTypes.func,
};

这是第一段代码。

class Organizations extends Component {
  constructor(props) {
    super(props);
    this.state = { organizations: [], mappedOrgs: [] };
  }

  //ORG LOAD
  componentDidMount() {
    paginatedList(0, 8).then(this.onOrgSuccess);
  }

  //ORG CALL SUCCESS

  onOrgSuccess = (config) => {
    let organizations = config.item.pagedItems;
    this.setState((prevState) => {
      return {
        ...prevState,
        mappedOrgs: organizations.map(this.mapOrg),
      };
    }, this.stateChanged);
  };

  mapOrg = (Organization) => (
    _logger(Organization, "ORGANIZATION, ORGANIZATION"),
    (
      <OrgCard
        Organization={Organization}
        key={Organization.id}
        editOrganization={this.editOrganization}
        deleteFunction={this.deleteFunction}
      />
    )
  );

  //DELETE

  deleteFunction = (deletedOrg) => {
    this.setState((prevState) => {
      const indexOfOrg = prevState.mappedOrgs.findIndex(
        (Org) => Org.id === deletedOrg.id
      );
      let updatedOrgs = [...prevState.mappedOrgs];
      if (indexOfOrg >= 0) {
        updatedOrgs.slice(indexOfOrg, 1);
      }
      _logger(updatedOrgs);

      return { mappedOrgs: updatedOrgs };
    }, this.stateChanged);
  };

  //MAP ORG


  editOrganization = (Organization) => {
    this.props.history.push(
      `/organization/${Organization.id}/edit`,
      Organization
    );
  };
  //RENDER
  render() {
    return (
      <div className="col-12">
        <div className="row">{this.state.mappedOrgs}</div>
      </div>
    );
  }
}

Organizations.propTypes = {
  history: PropTypes.shape({
    push: PropTypes.func,
  }),
  findIndex: PropTypes.func,
  deleteFunction: PropTypes.checkPropTypes({
    deletedOrg: PropTypes.number,
    mappedOrgs: PropTypes.array,
    findIndex: PropTypes.func,
    updatedOrgs: PropTypes.array,
    splice: PropTypes.func,
    indexOfOrg: PropTypes.number,
  }),
};

export default Organizations;

这是第二段代码。

const OrgCard = ({ Organization, editOrganization, deleteFunction }) => {
  //OPERATIONAL FUNCTIONS
  _logger(Organization);

  //DELETE
  const OrgDelete = () => {
    deleteOrg(Organization.id).then(deleteSuccess).catch(deleteToastFail);
  };

  //SUCCESS FUNCTIONS

  const deleteSuccess = () => {
    deleteFunction(Organization);
  };

  //FAIL FUNCTION

  const deleteToastFail = () => {
    toast.error("Delete Error", {
      closeOnClick: true,
      position: "top-center",
    });
  };

  //EDIT

  const handleEdit = () => {
    editOrganization(Organization);
  };

  return (
    <Card className="col-lg-6 col-md-6 col-sm-6">
      {" "}
      <CardHeader style={{ fontWeight: "bold" }} className="text-center">
        {Organization.name}
      </CardHeader>
      <CardBody>
        <CardImg src={Organization.logo} />
        {/* <CardText>
          <span>{Organization.description.slice(0, 120)}</span>
        </CardText> */}
        <CardText>
          <span>{Organization.id}</span>
        </CardText>
        <Button
          onClick={handleEdit}
          className="btn-sucess btn-lg center"
          align="center"
        >
          Edit
        </Button>
        <Button
          onClick={OrgDelete}
          className="btn-danger btn-lg center"
          align="center"
        >
          Delete
        </Button>
      </CardBody>
    </Card>
  );
};

OrgCard.propTypes = {
  Organization: PropTypes.shape({
    id: PropTypes.number,
    OrganizationTypeId: PropTypes.number,
    name: PropTypes.string,
    description: PropTypes.string,
    logo: PropTypes.string,
    locationId: PropTypes.number,
    phone: PropTypes.string,
    siteUrl: PropTypes.string,
  }).isRequired,
  deleteOrg: PropTypes.func,
  deleteFunction: PropTypes.func,
  editOrganization: PropTypes.func,
};

export default OrgCard;

在此处输入图像描述

标签: arraysreactjsreact-nativeformik

解决方案


你能澄清为什么你将数组从孩子传回给父母吗?

我相信正确的结构是父级将数组存储在其状态中。然后它可以将数组传递给孩子。它还应该将删除函数传递给子进程(该函数应该将索引作为参数)。此函数在父级中定义。父级通过传递函数的名称将函数传递给子级。如果孩子想从数组中删除一个项目,那么它将调用该函数并将要删除的项目的索引传递给它。然后该函数(位于父级中)将从其数组(存储在该父级的状态中)中删除该项目。这将自动导致子元素中显示的数组也更新。

这个想法是数组应该只从父级传递给子级。父级应处理所有数组操作。子级只应通过调用带有相关参数(例如索引)的函数(从父级传递给它)将有关数组的信息传递给父级。


推荐阅读