Хотите установить состояние один раз при первом рендеринге, не вызывая повторных рендеров при последующих обновлениях - PullRequest
1 голос
/ 28 мая 2020

У меня есть компонент 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 Ответ

1 голос
/ 28 мая 2020

Почему, тогда вы никогда не будете пересчитывать defaultMarket, если tickers когда-либо обновляется.

Если вы действительно хотите, вы можете добавить отключение eslint для строки и использовать пустой массив зависимостей, чтобы крючок запускается один раз только на креплении компонента.

const defaultMarket = useMemo(
  () =>
    tickers.find((ticker) => {
      return ticker.market_id === "BTC-USD";
    }),
  // eslint-disable-next-line react-hooks/exhaustive-deps
  []
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...