Хотите установить состояние один раз при первом рендеринге, не вызывая лишних повторных рендеров при последующих обновлениях
У меня есть MarketOverview
компонент, который отображает множество парных рынков для торговли криптовалютой. При инициализации я хочу, чтобы он отображалBTC/USD
рынок по умолчанию, что я делаю через useEffect()
. Проблема в томdefaultMarket
вызывается при каждом рендере. Кроме того,defaultMarket
зависит от tickers
опора, поэтому, если я заверну его в useMemo()
, то плагин eslint react-hooks автоматически заполняет tickers
как зависимость.
Без useMemo()
:
const defaultMarket = tickers.find((ticker) => {
return ticker.market_id === "BTC-USD";
});
С участием useMemo()
:
const defaultMarket = useMemo(
() =>
tickers.find((ticker) => {
return ticker.market_id === "BTC-USD";
}),
[tickers]
);
Весь компонент:
export const MarketOverview = memo(({ tickers }: TProps) => {
// Set default market on initialisation to BTC/USD
const defaultMarket = tickers.find((ticker) => {
return ticker.market_id === "BTC-USD";
});
const [selectedMarket, setSelectedMarket] = useState<ITicker | undefined>(
undefined
);
useEffect(() => {
setSelectedMarket(defaultMarket);
}, [defaultMarket]);
// Select market
const selectMarket = (market: ITicker) => {
history.push(`${PUBLIC_URL}/markets/${market.market_id}`);
setSelectedMarket(market);
};
return (
<div className="market-overview-container">
<MarketSelector
tickers={tickers}
selectMarket={selectMarket}
selectedMarket={selectedMarket}
/>
{selectedMarket && <MarketStats selectedMarket={selectedMarket} />}
</div>
);
});
1 ответ
Почему тогда ты никогда не пересчитаешь defaultMarket
если tickers
когда-либо обновляется.
Если вы действительно хотите, вы можете добавить отключение eslint для строки и использовать пустой массив зависимостей, чтобы ловушка запускалась один раз только при монтировании компонента.
const defaultMarket = useMemo(
() =>
tickers.find((ticker) => {
return ticker.market_id === "BTC-USD";
}),
// eslint-disable-next-line react-hooks/exhaustive-deps
[]
);