Fox7777
@Fox7777
Люблю python

Почему при добавлении навигационной панели на страницу профиля происходит бесконечный цикл запросов на сервер?

Я разрабатываю React-приложение, используя Ant Design для UI-компонентов и Effector для управления состоянием. У меня есть компонент Navbar, который работает нормально на других страницах, но когда я добавляю его на страницу Profile, это вызывает бесконечный цикл запросов на сервер.

Вот код моего компонента RightMenu, который используется внутри Navbar:
import { Menu, Avatar, Button, Spin } from "antd";
import { Link, useNavigate } from "react-router-dom";
import {
    UserOutlined,
    CodeOutlined,
    LogoutOutlined,
    PlusOutlined,
    LoginOutlined,
} from "@ant-design/icons";
import type { MenuProps } from "antd";
import { $token, tokenExprired } from "../../shared/auth";
import { useUnit } from "effector-react";
import { BizRoutes } from "../../utils/const";
import { useEffect } from "react";
import { $userBusinesses, getUserBusinessesFx } from "../../pages/Home";
import { Business } from "../../shared/api/business/model";
import { useProfile } from "../../pages/Profile";

interface RightMenuProps {
    mode: "horizontal" | "vertical" | "inline";
}

const RightMenu = ({ mode }: RightMenuProps) => {
    const navigate = useNavigate();
    const [user, loading] = useProfile();
    const [userBusinesses, businessesLoading, token] = useUnit([
        $userBusinesses,
        getUserBusinessesFx.pending,
        $token,
    ]);

    useEffect(() => {
        if (token) {
            getUserBusinessesFx(token);
        }
    }, [token]);

    const logoutHandler = () => {
        tokenExprired();
        localStorage.removeItem("token");
        navigate("/");
    };

    if (loading || businessesLoading) {
        return <Spin />;
    }

    const getMenuItems = () => {
        if (user) {
            switch (user.role) {
                case "admin":
                    return [
                        {
                            key: "project",
                            label: (
                                <Link to="/dashboard">
                                    <CodeOutlined /> Панель управления
                                </Link>
                            ),
                        },
                        {
                            key: "about-us",
                            label: (
                                <Link to={BizRoutes.PROFILE}>
                                    <UserOutlined /> Профиль
                                </Link>
                            ),
                        },
                        {
                            key: "log-out",
                            label: (
                                <Button type="link" onClick={logoutHandler}>
                                    <LogoutOutlined /> Выход
                                </Button>
                            ),
                        },
                    ];
                case "business":
                    return [
                        {
                            key: "about-us",
                            label: (
                                <Link to={BizRoutes.PROFILE}>
                                    <UserOutlined /> Профиль
                                </Link>
                            ),
                        },
                        ...userBusinesses.map((business: Business) => ({
                            key: business._id,
                            label: (
                                <Link
                                    to={`${BizRoutes.BUSINESS}/${business._id}`}
                                >
                                    {business.name}
                                </Link>
                            ),
                        })),
                        {
                            key: "log-out",
                            label: (
                                <Button type="link" onClick={logoutHandler}>
                                    <LogoutOutlined /> Выход
                                </Button>
                            ),
                        },
                    ];
                default:
                    return [
                        {
                            key: "about-us",
                            label: (
                                <Link to={BizRoutes.PROFILE}>
                                    <UserOutlined /> Профиль
                                </Link>
                            ),
                        },
                        {
                            key: "add-business",
                            label: (
                                <Link to={BizRoutes.ADDBUSINESS}>
                                    <PlusOutlined /> Создать бизнес
                                </Link>
                            ),
                        },
                        {
                            key: "log-out",
                            label: (
                                <Button type="link" onClick={logoutHandler}>
                                    <LogoutOutlined /> Выход
                                </Button>
                            ),
                        },
                    ];
            }
        } else {
            return [
                {
                    key: "log-in",
                    label: (
                        <Link to={BizRoutes.LOGIN}>
                            <LoginOutlined /> Вход
                        </Link>
                    ),
                },
                {
                    key: "register",
                    label: (
                        <Link to={BizRoutes.REGISTRATION}>
                            <UserOutlined /> Регистрация
                        </Link>
                    ),
                },
            ];
        }
    };

    const items: MenuProps["items"] = [
        {
            key: "sub1",
            label: (
                <>
                    <Avatar icon={<UserOutlined />} />
                    <span className="username">
                        {user ? user.name : "Guest"}
                    </span>
                </>
            ),
            children: getMenuItems(),
        },
    ];

    return <Menu mode={mode} items={items} />;
};

export default RightMenu;


И вот хук useProfile:
import { useEffect } from 'react';
import { useUnit } from 'effector-react';
import { $user, getUserFx } from '../index';
import { $token } from '../../../shared/auth';

export const useProfile = () => {
  const [user, loading, token] = useUnit([$user, getUserFx.pending, $token]);

  useEffect(() => {
    if (token) {
      getUserFx(token);
    }
  }, [token]);

  return [user, loading] as const;
};


Наконец, мой компонент Profile, где происходит проблема:
import Navbar from "../../../components/Navigation";
import { Spin } from "antd";
import { useProfile } from "../hooks/useProfile";

const Profile = () => {
    const [user, loading] = useProfile();
    if (loading) {
        return <Spin />;
    }
    return (
        <div>
            <Navbar />
            {user ? (
                <>
                    <h1>
                        Welcome, {user.name} {user.surname}
                    </h1>
                    <p>Role: {user.role}</p>
                    <p>Email: {user.email}</p>
                    <p>Phone: {user.phone}</p>
                </>
            ) : (
                <>
                    <h1>Профиль</h1>
                    <p>Нет доступных пользовательских данных.</p>
                </>
            )}
        </div>
    );
};

export default Profile;


Когда я добавляю компонент <Navbar /> на страницу Profile, это вызывает бесконечный цикл запросов на сервер. Закомментирование <Navbar /> останавливает бесконечные запросы, и Navbar работает нормально на других страницах.

Что может быть причиной этого бесконечного цикла при добавлении Navbarна мою страницу Profile, и как это можно исправить?

Дополнительная информация:

Я использую Effector для управления состоянием.
Компонент RightMenu внутри Navbar получает бизнесы пользователя на основе токена.
Хук useProfile получает данные пользователя также на основе токена.
Буду благодарен за любые идеи и предложения по решению этой проблемы!
  • Вопрос задан
  • 44 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы