There is a Playlist component, user can choose different tag show different data. And some tag has banner and some not. The data are all fetched by reduxt-toolkit-query.
- hightqualityTags.tags: a tag array which has banner
It seems setBannerVisibility()
be used in wrong place...
Playlist.jsx
import { useState } from "react";
import HighqualityBanner from "../components/Playlist/HighqualityBanner";
import Catlist from "../components/Playlist/Catlist";
import PlaylistItem from "../components/Playlist/PlaylistItem";
import { useGetPlaylistHighqualityTagsQuery } from "../redux/services/neteaseCloudMusic";
const Playlist = () => {
// tag logic
const initialTag = "全部歌单";
const [currentTag, setCurrentTag] = useState(initialTag);
const onSelectTag = (tag) => {
setCurrentTag(tag);
};
//set banner visibility
const [bannerVisibility, setBannerVisibility] = useState(true);
const { data: hightqualityTags } = useGetPlaylistHighqualityTagsQuery();
if (hightqualityTags && hightqualityTags.tags) {
const exist = hightqualityTags.tags.find((tag) => tag.name === currentTag);
if (currentTag === initialTag) {
setBannerVisibility(true);
} else {
setBannerVisibility(!!exist);
}
}
return (
<div>
{bannerVisibility && <HighqualityBanner />}
<Catlist
initialTag={initialTag}
tag={currentTag}
onSelectTag={onSelectTag}
/>
<div>
<PlaylistItem />
</div>
</div>
);
};
api
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
export const musicApi = createApi({
reducerPath: "musicApi",
baseQuery: fetchBaseQuery({
baseUrl: "https://music-api-33.vercel.app",
}),
endpoints: (builder) => ({
getRecommendBanner: builder.query({ query: () => "/banner" }),
getPlaylistHotlist: builder.query({ query: () => "/playlist/hot" }),
getPlaylistCatlist: builder.query({ query: () => "/playlist/catlist" }),
getPlaylistHighqualityTags: builder.query({
query: () => "/playlist/highquality/tags",
}),
}),
});
export const {
useGetRecommendBannerQuery,
useGetPlaylistHotlistQuery,
useGetPlaylistCatlistQuery,
useGetPlaylistHighqualityTagsQuery,
} = musicApi;
I want to find currentTag is or isn't existing in the hightqualityTags.tags
and according the result to set the banner's visiblity. I'm new to redux-toolkit-query, I try to read the docs but it's hard to me.
CodePudding user response:
too many rerenders occur due to the fact that you change the state of the component every time its state changes in the if()
block. I.e., looping occurs.
You need to wrap your if block in useEffect(() => {})
and everything should work out.
const Playlist = () => {
// tag logic
const initialTag = "全部歌单";
const [currentTag, setCurrentTag] = useState(initialTag);
const onSelectTag = (tag) => {
setCurrentTag(tag);
};
//set banner visibility
const [bannerVisibility, setBannerVisibility] = useState(true);
const { data: hightqualityTags } = useGetPlaylistHighqualityTagsQuery();
useEffect(() => {
if (hightqualityTags && hightqualityTags.tags) {
const exist = hightqualityTags.tags.find((tag) => tag.name === currentTag);
if (currentTag === initialTag) {
setBannerVisibility(true);
} else {
setBannerVisibility(!!exist);
}
}
}, [currentTag, hightqualityTags])
return (
<div>
{bannerVisibility && <HighqualityBanner />}
<Catlist
initialTag={initialTag}
tag={currentTag}
onSelectTag={onSelectTag}
/>
<div>
<PlaylistItem />
</div>
</div>
);
};
Do not allow the state of the component to change outside of functions or events. Remember that React functional components behave like normal functions, i.e. when the state changes, they are executed completely and render() is terminated.