我构建了一个 MERN 项目,其中组件 FrindListWidget 在 2 个条件下被调用。
user.friends 中的状态也会更新。 每个 Friend 还包含一个 ,它将添加或删除 Friend。
显然,在我检查 Chrome 开发者工具中的网络选项卡之前,一切都运行得很好。我检测到 friends 被无限次调用。为了说清楚,我写了console.log("friends",friends);。是的,它被记录了无数次。
我分享以下代码:
FriendListWidget.jsx
//other mui imports
import { WidgetWrapper } from "../../../components/StyledComponent/WidgetWrapper";
import { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { setFriends as setUsersFriends } from "../../../Redux/Slices/authSlice";
import { userRequest } from "../../../requestMethod";
import Friend from "../../../components/Friend";
const FriendListWidget = ({ userId }) => {
const dispatch = useDispatch();
const { palette } = useTheme();
const [friends, setFriends] = useState([]);
const user = useSelector((state) => state.user);
const getFriends = async () => {
const res = await userRequest.get(`/users/${userId}/friends`);
const data = await res.data;
if (user._id === userId) {
dispatch(setUsersFriends({ friends: data }));
setFriends(data);
} else {
setFriends(data);
}
};
useEffect(() => {
getFriends();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [user, userId]);
console.log("friends", friends); //This is being logged for infinite times
return (
<WidgetWrapper>
<Typography
color={palette.neutral.dark}
variant="h5"
fontWeight="500"
sx={{ mb: "1.5rem" }}
>
Friend List
</Typography>
<Box display="flex" flexDirection="column" gap="1.5rem">
{friends.map((friend) => (
<Friend
key={friend._id}
friendId={friend._id}
name={`${friend.firstName} ${friend.lastName}`}
subtitle={friend.occupation}
userPicturePath={friend.picturePath}
/>
))}
</Box>
</WidgetWrapper>
);
};
export default FriendListWidget;
Friend.jsx
//other mui imports
import { useDispatch, useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import { userRequest } from "../../requestMethod";
import { setFriends } from "../../Redux/Slices/authSlice";
import { FlexBetween } from "../StyledComponent/FlexBetween";
import UserImage from "../StyledComponent/UserImage";
const Friend = ({ friendId, name, location, userPicturePath }) => {
const dispatch = useDispatch();
const navigate = useNavigate();
const { _id } = useSelector((state) => state.user);
const friends = useSelector((state) => state.user.friends);
const { palette } = useTheme();
const primaryLight = palette.primary.light;
const primaryDark = palette.primary.dark;
const main = palette.neutral.main;
const medium = palette.neutral.medium;
const isFriend = friends.find((friend) => friend._id === friendId);
const isUser = friendId === _id;
const patchFriend = async () => {
const res = await userRequest.patch(`/users/${_id}/${friendId}`);
const data = await res.data;
dispatch(setFriends({ friends: data }));
};
return (
<FlexBetween>
<FlexBetween gap="1rem">
<UserImage image={userPicturePath} size="55px" />
<Box
onClick={() => {
navigate(`/profile/${friendId}`);
navigate(0);
}}
>
<Typography
color={main}
variant="h5"
fontWeight="500"
sx={{
"&:hover": {
color: palette.primary.light,
cursor: "pointer",
},
}}
>
{name}
</Typography>
<Typography color={medium} fontSize="0.75rem">
{location}
</Typography>
</Box>
</FlexBetween>
{!isUser && (
<IconButton
onClick={() => patchFriend()}
sx={{ backgroundColor: primaryLight, p: "0.6rem" }}
>
{isFriend ? (
<PersonRemoveOutlined sx={{ color: primaryDark }} />
) : (
<PersonAddOutlined sx={{ color: primaryDark }} />
)}
</IconButton>
)}
</FlexBetween>
);
};
export default Friend;
userRequest 只是一个 axios 方法:
export const userRequest = axios.create({
baseURL: BASE_URL,
headers: { token: `Bearer ${token}` },
});
我尝试删除 useEffect 挂钩中的依赖项:
useEffect(() => {
getFriends();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
但是,它只渲染一次。它不会在运行时通过 显示更新。我必须重新加载窗口才能看到更新。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
我假设你正在调用getFriends()函数,该函数会更新你在useEffect中注入的用户列表,因此,使得useEffect无限次更新自身,尝试让你的useEffect依赖于另一个值。
useEffect(() => { getFriends(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [userId]);对于这种情况,我个人使用react-query,并使用enabled属性来决定何时再次调用API,然而,你的逻辑存在严重问题,我无法理解它,如果你能够使用CodeSandBox等平台创建一个最小可复现的问题示例,我们可以更好地帮助你。