希望在第一次渲染时设置一次状态,而不会导致进一步更新时不必要的重新渲染 [英] Want to set state once on first render without causing uneccessary re-renders on further updates
问题描述
我有一个MarketOverview
组件,可渲染一堆加密货币交易对市场.初始化时,我希望它默认显示BTC/USD
市场,这是通过useEffect()
完成的.问题在于defaultMarket
在每个渲染器上都被调用.而且,defaultMarket
依赖于tickers
道具,因此,如果将其包装在useMemo()
中,则eslint react-hooks插件会自动将tickers
填充为依赖项.
I have a MarketOverview
component that renders a bunch of cryptocurrency trading pair markets. On initialisation, I want it to render the BTC/USD
market by default, which I'm doing via useEffect()
. The problem is the defaultMarket
gets called on every render. Moreover, defaultMarket
depends on the tickers
prop, so if I wrap it in useMemo()
, then the eslint react-hooks plugin automatically populates tickers
as a dependency.
没有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>
);
});
推荐答案
为什么,如果tickers
曾经更新,那么您将永远不会重新计算defaultMarket
.
Why, then you'll never recompute defaultMarket
if tickers
ever updates.
但是,如果您确实愿意,可以为该行添加eslint禁用,并使用一个空的依赖项数组,以便该挂钩仅在组件安装时运行一次.
If you really want to though, you can add an eslint disable for the line and use an empty dependency array so the hook runs once only on component mount.
const defaultMarket = useMemo(
() =>
tickers.find((ticker) => {
return ticker.market_id === "BTC-USD";
}),
// eslint-disable-next-line react-hooks/exhaustive-deps
[]
);
这篇关于希望在第一次渲染时设置一次状态,而不会导致进一步更新时不必要的重新渲染的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!