Я разрабатываю 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
получает данные пользователя также на основе токена.
Буду благодарен за любые идеи и предложения по решению этой проблемы!