Heim  >  Fragen und Antworten  >  Hauptteil

Unbegrenzte API-Aufrufe, ausgelöst durch UseEffect

Ich habe ein MERN-Projekt erstellt, bei dem die Komponente FrindListWidget unter zwei Bedingungen aufgerufen wird.

  1. Wenn es sich um die eigene Freundesliste des Benutzers handelt, wird das Widget gerendert und der Status in Redux user.friends aktualisiert.
  2. Wenn es sich um einen anderen Benutzer handelt, wird nur das Widget gerendert. Der Redux-Status wird nicht aktualisiert.

Alle Friend 还包含一个 ,它将添加或删除 Friend. Anscheinend hat alles gut funktioniert, bis ich die Registerkarte „Netzwerk“ in den Chrome Developer Tools überprüft habe. Ich habe erkannt. Ja, es wurde mehrfach aufgenommen. Ich teile den folgenden Code: 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

ist nur eine Axios-Methode:

export const userRequest = axios.create({
  baseURL: BASE_URL,
  headers: { token: `Bearer ${token}` },
});
Ich habe versucht, die Abhängigkeit im useEffect-Hook zu entfernen:

useEffect(() => {
    getFriends();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

Es wird jedoch nur einmal gerendert. Während der Ausführung werden keine Updates über

angezeigt. Ich muss das Fenster neu laden, um die Updates zu sehen.

P粉501683874P粉501683874417 Tage vor512

Antworte allen(1)Ich werde antworten

  • P粉156532706

    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等平台创建一个最小可复现的问题示例,我们可以更好地帮助你。

    Antwort
    0
  • StornierenAntwort