希望在第一次渲染时设置一次状态,而不会在进一步更新时导致不必要的重新渲染

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 作为依赖项填充。

没有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

如果你真的想要,你可以为该行添加一个 eslint 禁用并使用一个空的依赖数组,这样挂钩只在组件挂载时运行一次。

const defaultMarket = useMemo(
  () =>
    tickers.find((ticker) => {
      return ticker.market_id === "BTC-USD";
    }),
  // eslint-disable-next-line react-hooks/exhaustive-deps
  []
);