J'ai construit un projet MERN où le composant FrindListWidget
est appelé sous 2 conditions.
user.friends
est mis à jour. Tous les Friend
还包含一个
,它将添加或删除 Friend
.
Apparemment, tout fonctionnait bien jusqu'à ce que je vérifie l'onglet Réseau dans les outils de développement Chrome. J'ai détecté friends
被无限次调用。为了说清楚,我写了console.log("friends",friends);
. Oui, cela a été enregistré à plusieurs reprises.
Je partage le code suivant :
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 n'est qu'une méthode axios :
export const userRequest = axios.create({ baseURL: BASE_URL, headers: { token: `Bearer ${token}` }, });
J'ai essayé de supprimer la dépendance dans le hook useEffect :
useEffect(() => { getFriends(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []);
Cependant, il n'est rendu qu'une seule fois. Il n'affichera pas les mises à jour via
pendant l'exécution. Je dois recharger la fenêtre pour voir les mises à jour.
Je suppose que vous appelez la fonction getFriends() qui met à jour la liste d'utilisateurs que vous avez injectée dans useEffect, par conséquent, en faisant en sorte que useEffect se mette à jour un nombre infini de fois, essayez de rendre votre useEffect dépendant d'une autre valeur.
Pour ce cas, j'utilise personnellement réagir-query et j'utilise l'attribut activé pour décider quand appeler à nouveau l'API. Cependant, il y a quelque chose qui ne va vraiment pas avec votre logique et je ne peux pas le comprendre, si vous parvenez à créer un requête réutilisable minimale utilisant une plateforme comme CodeSandBox Exemples de problèmes récurrents afin que nous puissions mieux vous aider.