[英]useEffect refetch everytime when data is changed.How to achive it?
我有这个自定义钩子来获取我的数据,但我在渲染时只获取一次有问题,我知道它的数组在使用效果上是空的,但是当把setPartData和url或data.data放在那里时,它变得像无限循环如何避免这种情况。
每次数据更改时如何在不占用计算机 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;
};
以及我使用它的组件
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 />;
}
删除我需要重新加载页面以获取更新的位置 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>
);
};
您需要使用另一个 state 变量,您可以在其中存储最近删除的元素 ID。 useEffect 必须与该变量挂钩。 如果该 ID 发生更改,则 useEffect 将获取新数据。
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.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.