Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
184 views
in Technique[技术] by (71.8m points)

javascript - Automaticly update component when item delete

Problem

I have code which deletes a component. It works, but when I click delete button, I need to reload browser to see it's deleted.

Is there a way to immediately show page without this element? I tried a few things, but nothing works form me. Is rerender the only soultion??? Maybe I should use state managment like 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>
  );
};

And Main component 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;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I don't think you need something like redux for this.

To get around your problem, I would do the following:

In the Main Component, update the album constant to const [albums, setAlbums] = useState(data.data);

Create a function in the Main Component:

const handleDelete = id => {
    setAlbums(albums => albums.filter(album => album._id != id));
}
  • Note that as now albums is a state variable, creating a new array with filter will cause the component to re-render when handleDelete is called.

In your Card Component, accept a new prop called onDelete, and pass the new function handleDelete from your Main Component into it like so:

<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}
>

and:

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

In the handleDelete function of your Card Component, after doing the DELETE request, simply call onDelete(id)

And just like that, you should have the functionality that you're requesting. Let me know if there are any issues!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...