希望在第一次渲染时设置一次状态,而不会导致进一步更新时不必要的重新渲染 [英] Want to set state once on first render without causing uneccessary re-renders on further updates

查看:229
本文介绍了希望在第一次渲染时设置一次状态,而不会导致进一步更新时不必要的重新渲染的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆