Want to set state once on first render without causing uneccessary re-renders on further updates

て烟熏妆下的殇ゞ 提交于 2020-08-09 13:32:07

问题


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.

Without useMemo():

const defaultMarket = tickers.find((ticker) => {
    return ticker.market_id === "BTC-USD";
  });

With useMemo():

const defaultMarket = useMemo(
    () =>
      tickers.find((ticker) => {
        return ticker.market_id === "BTC-USD";
      }),
    [tickers]
  );

Entire component:

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:


Why, then you'll never recompute defaultMarket if tickers ever updates.

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
  []
);


来源:https://stackoverflow.com/questions/62057343/want-to-set-state-once-on-first-render-without-causing-uneccessary-re-renders-on

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!