我建立了一個 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 }, []);
但是,它只渲染一次。它不會在運行時透過
顯示更新。我必須重新加載視窗才能看到更新。
P粉1565327062023-09-21 09:41:39
我假設你正在調用getFriends()函數,該函數會更新你在useEffect中註入的用戶列表,因此,使得useEffect無限次更新自身,嘗試讓你的useEffect依賴於另一個值。
useEffect(() => { getFriends(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [userId]);
對於這種情況,我個人使用react-query,並使用enabled屬性來決定何時再次呼叫API,然而,你的邏輯存在嚴重問題,我無法理解它,如果你能夠使用CodeSandBox等平台創建一個最小可復現的問題範例,我們可以更好地幫助你。