提问人:imshoaibkhan 提问时间:11/17/2023 更新时间:11/17/2023 访问量:59
在 React 中获得太多的重新渲染
getting too many re-renders in react
问:
我有一个名为 Search
的 React 组件,我在其中迭代数据项并为每个项呈现一个 SearchCard
组件。SearchCard
组件包含用于处理播放和暂停操作的逻辑。我注意到 SearchCard
组件中的控制台日志被多次触发,并且还发出了多个获取请求。
// SearchCard.jsx
import { useDispatch } from "react-redux";
import { Link } from "react-router-dom";
import PlayPause from "./PlayPause";
import { playPause, setActiveSong } from "../redux/features/playerSlice";
import { useEffect, useState } from "react";
const SearchCard = ({ song, i, isPlaying, activeSong, data }) => {
const dispatch = useDispatch();
console.log('heyyy!'); // This log statement is appearing multiple times
const handlePauseClick = () => {
dispatch(playPause(false));
};
const handlePlayClick = () => {
dispatch(setActiveSong({ data, song, i }));
dispatch(playPause(true));
};
// ... rest of the component
return (
// ... component JSX
);
};
export default SearchCard;
// Search.jsx
import React from 'react';
import { useSelector } from 'react-redux';
import { useParams } from 'react-router-dom';
import { Error, Loader, SearchCard } from '../components';
import { useGetSongsBySearchQuery } from '../redux/services/shazam';
const Search = () => {
const { searchTerm } = useParams();
const { activeSong, isPlaying } = useSelector((state) => state.player);
const { data, isFetching, error } = useGetSongsBySearchQuery(searchTerm);
const songs = data?.tracks?.map((song) => song.data);
if (isFetching) return <Loader title={`Searching ${searchTerm}...`} />;
if (error) return <Error />;
return (
<div className="flex flex-col">
<h2 className="font-bold text-3xl text-white text-left mt-4 mb-10">
Showing results for <span className="font-black">{searchTerm}</span>
</h2>
<div className="flex flex-wrap sm:justify-start justify-center gap-8">
{songs.map((song, i) => (
<SearchCard
key={song.id}
song={song}
isPlaying={isPlaying}
activeSong={activeSong}
data={data.tracks}
i={i}
/>
))}
</div>
</div>
);
};
export default Search;
预期行为:我希望 SearchCard
组件只记录一次,并且每个渲染的实例只获取一次数据。但是,它似乎多次记录和获取数据,导致意外行为。
答:
-1赞
Kumar Shanu
11/17/2023
#1
您在 songs.map 中使用 SearchCard,因为对于每个迭代,都有一个控制台将记录假设您在 songs 数组中有五个元素,然后五个控制台将记录以避免这种情况 - 将您的网络调用移动到父级别
评论
0赞
Jaromanda X
11/17/2023
为什么这是报价?OP 的问题中没有 或showCard
array.map
0赞
Sachin Gautam
11/17/2023
#2
- 检查 useEffect 依赖项: 在 SearchCard.jsx 组件中,查看 useEffect 钩子(当前未显示在您提供的代码中),并确保已列出 useEffect 所依赖的所有依赖项。如果缺少任何依赖项,则可能导致意外行为。
2.优化渲染,避免副作用: 你可以使用 React.memo 来记住你的 SearchCard 组件,并在道具没有改变的情况下防止它重新渲染。但是,请记住,记忆是一种权衡,它可能并不适合所有方案。
在父组件中获取数据: 考虑将数据获取逻辑移动到父组件(在本例中为 Search.jsx),并将必要的数据作为 props 传递给 SearchCard 组件。这有助于集中数据提取并避免不必要的提取调用。
调试: 如果问题仍然存在,您可能需要使用浏览器开发人员工具来检查 React 组件树,并检查哪些组件正在渲染并导致额外的渲染。这可以帮助您确定意外行为的根本原因。
评论