I have a MarketList
component that fetches market id's and a MarketCard
component that fetches info for a given market based on the id. Because I want the markets to be filterable by info, I'm saving the market info in the MarketList
component. However, this causes what appears to be n^2 re-renders.
MarketList
type Market = {
id: string;
};
type MarketInfo = {
[key: string]: { title: 'title'; description: 'description' };
};
const MarketList = () => {
const [markets, setMarkets] = useState<Market[]>([]);
const [marketsInfo, setMarketsInfo] = useState<MarketInfo>({});
useEffect(() => {
const fetchedMarkets = getMarkets();
setMarkets(fetchedMarkets);
}, []);
return (
<div>
{markets.map((market) => (
<MarketCard
key={market.id}
market={market}
marketInfo={marketsInfo[market.id]}
updateMarketInfo={(info) =>
setMarketsInfo((prevState) => ({ ...prevState, [market.id]: info }))
}
/>
))}
</div>
);
};
MarketCard
const MarketCard = (market, marketInfo, updateMarketInfo) => {
console.log('MARKET CARD');
useEffect(() => {
if (marketInfo) {
return;
}
const fetchedMarketInfo = getMarketInfo(market.id);
updateMarketInfo(fetchedMarketInfo);
}, [marketInfo]);
return <div>{marketInfo.title}</div>;
};
The async network requests themselves are near instant. I would like a Card component not to be re-rendered if the marketInfo
for a given Card exists.
screen grab of console:
CodePudding user response:
You can use React.memo (https://reactjs.org/docs/react-api.html#reactmemo) and pass a function to the second argument to react memo to only change if the specific info for the MarketCard component is changed.