1

问题

我有删除组件的代码。它可以工作,但是当我单击删除按钮时,我需要重新加载浏览器才能看到它已被删除。

有没有办法在没有这个元素的情况下立即显示页面?我尝试了一些东西,但对我来说没有任何效果。重新渲染是唯一的灵魂???也许我应该使用像 redux 这样的状态管理。

 const CardWithEdit = ({
  width,
  height,
  bckImg,
  color,
  children,
  link,
  editLink,
  id,
}) => {
  const [state, setState] = useState(false);
  const handleClick = () => setState(!state);

  const handleDelete = async () => {
    await fetch(`http://localhost:5000/api/v1/albums/${id}`, {
      method: "DELETE",
    });
    
    handleClick();
  };

  return (
    <Card width={width} height={height} bckImg={bckImg}>
      <AlbumtTitle color={color}>{children}</AlbumtTitle>
      <LinkButton background={color} to={link}>
        See more
      </LinkButton>
      <IconWrapper>
        <div>
          <Link to={editLink}>
            <AiOutlineEdit />
          </Link>
        </div>
        <div onClick={handleClick}>
          <AiOutlineDelete
            style={{
              cursor: "pointer",
            }}
          />
        </div>
      </IconWrapper>
      {state && (
        <Dialog
          handleClick={handleClick}
          handleDelete={handleDelete}
          deleteText={"Delete"}
        />
      )}
    </Card>
  );
};

和主要组件 albums.js

import React from "react";
import Loader from "../components/Loader";
import CardWithEdit from "../components/Card/CardWithEdit";
import ErrorMessage from "../components/ErrorMessage";
import { CartWrapper } from "../components/Wrappers";
import { apiStates, useApi } from "../hooks/useApi";
const Albums = () => {
  const { state, error, data } = useApi("http://localhost:5000/api/v1/albums");

  const albums = data.data;
  switch (state) {
    case apiStates.ERROR:
      return <ErrorMessage>{error || "General error"}</ErrorMessage>;
    case apiStates.SUCCESS:
      return (
        <CartWrapper>
          {albums.length > 0 ? (
            albums.map((album) => (
              <CardWithEdit
                width={"23rem"}
                height="16rem"
                color={album.color}
                bckImg={album.bckImgUrl}
                key={album._id}
                link={`/albums/${album._id}`}
                editLink={`edit/${album._id}`}
                id={album._id}
              >
                {album.name}
              </CardWithEdit>
            ))
          ) : (
            <h1>No albums yet</h1>
          )}
        </CartWrapper>
      );
    default:
      return <Loader />;
  }
};

export default Albums;
4

1 回答 1

1

我认为你不需要像 redux 这样的东西。

为了解决您的问题,我将执行以下操作:

在主组件中,将专辑常量更新为const [albums, setAlbums] = useState(data.data);

在主组件中创建一个函数:

const handleDelete = id => {
    setAlbums(albums => albums.filter(album => album._id != id));
}
  • 请注意,由于现在专辑是一个状态变量,因此使用过滤器创建一个新数组将导致组件在调用 handleDelete 时重新渲染。

在您的卡片组件中,接受一个名为 的新道具onDelete,然后将新函数handleDelete从您的主组件传递给它,如下所示:

<CardWithEdit
    width={"23rem"}
    height="16rem"
    color={album.color}
    bckImg={album.bckImgUrl}
    key={album._id}
    link={`/albums/${album._id}`}
    editLink={`edit/${album._id}`}
    id={album._id}
    onDelete={handleDelete}
>

和:

const CardWithEdit = ({
    width,
    height,
    bckImg,
    color,
    children,
    link,
    editLink,
    id,
    onDelete,
    }) => {

在您的 Card 组件的 handleDelete 函数中,执行 DELETE 请求后,只需调用onDelete(id)

就这样,您应该拥有您所要求的功能。让我知道是否有任何问题!

于 2020-12-26T23:50:41.347 回答