Panggilan API tanpa had yang dicetuskan oleh UseEffect
P粉501683874
P粉501683874 2023-09-20 20:50:56
0
1
457

Saya membina projek MERN di mana komponen FrindListWidget dipanggil di bawah 2 syarat.

  1. Jika senarai rakan pengguna sendiri, widget itu dipaparkan dan status dalam Redux user.friends dikemas kini.
  2. Jika pengguna lain, hanya widget yang akan dipaparkan. Keadaan Redux tidak dikemas kini.

Setiap Friend 还包含一个 ,它将添加或删除 Friend. Nampaknya, semuanya berfungsi dengan baik sehingga saya menyemak tab Rangkaian dalam Alat Pembangun Chrome. Saya mengesan friends 被无限次调用。为了说清楚,我写了console.log("friends",friends);. Ya, ia telah dirakam berkali-kali. Saya kongsikan kod berikut:

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 hanyalah kaedah aksios:

export const userRequest = axios.create({
  baseURL: BASE_URL,
  headers: { token: `Bearer ${token}` },
});

Saya cuba mengalih keluar kebergantungan dalam cangkuk useEffect:

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

Namun, ia hanya dipaparkan sekali. Ia tidak akan menunjukkan kemas kini melalui semasa berjalan. Saya perlu memuat semula tetingkap untuk melihat kemas kini.

P粉501683874
P粉501683874

membalas semua(1)
P粉156532706

Saya menganggap anda sedang memanggil fungsi getFriends() yang mengemas kini senarai pengguna yang anda suntik dalam useEffect, oleh itu, membuat kemas kini useEffect itu sendiri dalam masa yang tidak terhingga, cuba jadikan useEffect anda bergantung pada nilai lain.

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

Untuk kes ini, saya secara peribadi menggunakan react-query dan menggunakan atribut yang didayakan untuk memutuskan masa untuk memanggil API sekali lagi, namun, terdapat sesuatu yang salah dengan logik anda dan saya tidak dapat memahaminya, jika anda dapat mencipta pertanyaan boleh guna semula minimum menggunakan platform seperti CodeSandBox Contoh isu berulang supaya kami dapat membantu anda dengan lebih baik.

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!