简体   繁体   中英

useEffect refetch everytime when data is changed.How to achive it?

I have this custom hook to fetch my data but i have problem its fetch only once on render i know its becouse array on use effect its empty but when put there setPartData and url or data.data it becomes like infinite loop how to avoid this.

How to achive its refetch every time when data is change without burining my computer CPU.

import React, { useState, useEffect } from "react";

export const apiStates = {
  LOADING: "LOADING",
  SUCCESS: "SUCCESS",
  ERROR: "ERROR",
};

export const useApi = (url) => {
  const [data, setData] = useState({
    state: apiStates.LOADING,
    error: "",
    data: [],
  });

  const setPartData = (partialData) => setData({ ...data, ...partialData });

  useEffect(() => {
    setPartData({
      state: apiStates.LOADING,
    });
    fetch(url)
      .then((response) => response.json())
      .then((data) => {
        setPartData({
          state: apiStates.SUCCESS,
          data,
        });
      })
      .catch(() => {
        setPartData({
          state: apiStates.ERROR,
          error: "fetch failed",
        });
      });
  }, []);

  return data;
};

And component where i use it

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

Delete where i need to reload page to get updated state

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

You need to use another state variable, where you can store the recently deleted element ID. The useEffect will have to be hooked to that variable. If that ID, changes, the useEffect will fetch new data.

const [deleteID, setDeleteID] = useState(null);  //update this in the delete component

  useEffect(() => {
setPartData({
  state: apiStates.LOADING,
});
fetch(url)
  .then((response) => response.json())
  .then((data) => {
    setPartData({
      state: apiStates.SUCCESS,
      data,
    });
  })
  .catch(() => {
    setPartData({
      state: apiStates.ERROR,
      error: "fetch failed",
    });
  });
  }, [deleteID]); //useEffect will only fire when delete ID changes.
 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM