При перезагрузке страницы, у меня обнуляется favorite
При перезагрузке страницы, у меня обнуляется favorite. И если стоял лайк, то он не стоит, хотя счетчик и все данные полученные из data верные
файл с ошибкой:
import { Link, useNavigate, useParams } from "react-router-dom";
import { useGetArticleQuery } from "../../redux/defaulApi";
import { format } from "date-fns";
import styleArticleFull from "./ArticleFull.module.scss";
import Markdown from "markdown-to-jsx";
import { Flex, Spin, Alert } from "antd";
import { LoadingOutlined } from "@ant-design/icons";
import { QuestionCircleOutlined } from "@ant-design/icons";
import { Button, Popconfirm } from "antd";
export default function ArticleFull() {
const navigate = useNavigate();
const { slug } = useParams();
const user = JSON.parse(localStorage.getItem("user-info"));
const [delArticle] = useArticleDeleteMutation();
const { data, isLoading, error } = useGetArticleQuery(slug, { refetchOnMountOrArgChange: true });
const [addFavotite] = useAddFavoriteMutation();
const [removeFavorite] = useRemoveFavoriteMutation();
const deleteArticle = () => {
delArticle(data?.article?.slug);
navigate("/");
};
const deleteLike = async () => {
try {
console.log("del");
await removeFavorite(slug);
} catch (error) {
console.log(error);
}
};
const addLike = async () => {
try {
console.log("add");
await addFavotite(slug);
} catch (error) {
console.error(error);
}
};
const editingPanel =
user?.username == data?.article?.author?.username ? (
<div className={styleArticleFull.editButtons}>
<Popconfirm
onConfirm={deleteArticle}
title="Delete the article"
description="Are you sure to delete this article?"
icon={
<QuestionCircleOutlined
style={{
color: "red",
}}
/>
}
>
<Button danger>Delete</Button>
</Popconfirm>
<Link to={`/articles/${slug}/edit`} className={styleArticleFull.btnEdit}>
Edit
</Link>
</div>
) : null;
if (error)
return (
<Flex justify="center">
<Alert
message="There's been some kind of mistake, we're already figuring it out!"
type="error"
showIcon
/>
</Flex>
);
if (isLoading)
return (
<Flex align="center" justify="center">
<Spin indicator={<LoadingOutlined style={{ fontSize: 48 }} spin />} />
</Flex>
);
const liker = data?.article?.favorited ? (
<span className={`${styleArticleFull.heart} ${styleArticleFull.heart_on}`} onClick={deleteLike}></span>
) : (
<span className={styleArticleFull.heart} onClick={addLike}></span>
);
return (
<>
<div className={styleArticleFull.articleFullContainer}>
<div className={styleArticleFull.articleContainer}>
<div className={styleArticleFull.infoContainer}>
<div className={styleArticleFull.infoTitleBox}>
<div className={styleArticleFull.titleBox}>
<h2 className={styleArticleFull.title}>{data?.article?.title}</h2>
<label className={styleArticleFull.liker}>
{liker}
{data?.article?.favoritesCount}
</label>
</div>
<div className={styleArticleFull.tagsBox}>
{data?.article?.tagList.map((item, index) => (
<p className={styleArticleFull.tag} key={index}>
{item}
</p>
))}
</div>
</div>
<div className={styleArticleFull.userInfo}>
<div className={styleArticleFull.userDescription}>
<h2 className={styleArticleFull.userName}>{data?.article?.author?.username}</h2>
<p className={styleArticleFull.date}>
{format(new Date(data?.article?.updatedAt), "MMM d, yyyy")}
</p>
</div>
<img className={styleArticleFull.userPic} src={data?.article?.author?.image} alt="аватар" />
</div>
</div>
<div className={styleArticleFull.descriptionPanel}>
<p className={styleArticleFull.description}>{data?.article?.description}</p>
{editingPanel}
</div>
</div>
<Markdown className={styleArticleFull.markdown}>{data?.article.body}</Markdown>
</div>
</>
);
}
default Api:
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
export const articlesApi = createApi({
reducerPath: "arcticlesApi",
baseQuery: fetchBaseQuery({
baseUrl: "https://blog-platform.kata.academy/api/",
prepareHeaders: (headers, { getState }) => {
const token = getState()?.user?.user?.token;
if (token) {
headers.set("Authorization", `Bearer ${token}`);
}
return headers;
},
}),
getArticle: build.query({
query: slug => `articles/${slug}`,
providesTags: ["Article", "Articles"],
}),
});
export const { useGetArticleQuery } = articlesApi;
Ответы (1 шт):
Автор решения: Greblin
→ Ссылка
useEffect(() => {
const userInfo = JSON.parse(localStorage.getItem('user-info'));
dispatch(signInUser(userInfo));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
Тут вспомогательные редьюсеры:
import { createSlice } from '@reduxjs/toolkit';
const userSlice = createSlice({
name: 'user',
initialState: {
user: {},
},
reducers: {
signInUser(state, action) {
state.user = { ...action.payload };
},
logOutUser(state) {
state.user = {};
},
loginStart(state) {
state.user = { ...JSON.parse(localStorage.getItem('user-info')) };
},
},
});
export const { signInUser, logOutUser, loginStart } = userSlice.actions;
export default userSlice.reducer;
Такая конструкция починила всё, в локальном хранилище находятся данные авторизованного пользователя.