Понимание необходимости использования хука useEvent() React.

Всем привет,

В этом посте мы попробуем разобраться в необходимости использования хука useEvent React и увидим, какую проблему команда React пытается решить с помощью этого хука.

Примечание: useEvent пока не является частью React, это просто предложение для решения проблемы ненужного рендеринга.

Если вы предпочитаете видео-версию этого поста, то вот она:

2 недели назад команда React предложила RFC, в котором они представили новый хук React под названием useEvent.

Давайте разберем этот RFC на двух примерах.

Пример первый

import { useState, useCallback } from "react";

export default function App() {
  const [count, setCount] = useState(0);

  const incrementCount = useCallback(() => {
    setCount(count + 1);
  }, [count]);

  return (
    <div className="App">
      <span>{count}</span>
      <button onClick={incrementCount}>SUBSCRIBE</button>
    </div>
  );
}
Вход в полноэкранный режим Выход из полноэкранного режима

Приведенный выше код выглядит совершенно нормально, это довольно простой компонент счетчика. Но проблема заключается в обработчике incrementCount.

Каждый раз, когда счетчик изменяется, компонент рендерится, и при каждом рендеринге обработчик incrementCount создается заново.

Это не является проблемой для такого маленького примера, но в больших приложениях это может создать проблему с производительностью и оптимизацией.

Даже если мы использовали хук useCallback, но поскольку useCallback принимает count в массиве зависимостей, проблема остается той же. При каждом изменении count useCallback будет запускаться снова.

Решение: на помощь приходит useEvent.

UseEvent решает вышеописанную проблему двумя способами:

  • Отсутствие массива зависимостей: useEvent не будет иметь массива зависимостей, следовательно, не будет перерисовки при каждом изменении состояния.
  • Доступ к обновленным состояниям: useEvent всегда будет иметь доступ к последним состояниям благодаря закрытию.

Когда useEvent будет доступен для использования, решение будет выглядеть примерно так, как показано ниже.

import { useState, useEvent } from "react";

export default function App() {
  const [count, setCount] = useState(0);

  const incrementCount = useEvent(() => {
    setCount(count + 1);
  });

  return (
    <div className="App">
      <span>{count}</span>
      <button onClick={incrementCount}>SUBSCRIBE</button>
    </div>
  );
}
Вход в полноэкранный режим Выход из полноэкранного режима

Пример второй

import { useState, useEffect } from "react";

export default function App() {
  const [routeUrl, setRouteUrl] = useState("/home");
  const [userName, setUserName] = useState("Swastik");

  const logAnalytics = (routeUrl, userName) => {
    console.log(`Route changed by ${userName} to ${routeUrl}`);
  };

  useEffect(() => {
    logAnalytics(routeUrl, userName);
  }, [logAnalytics, routeUrl, userName]);

  return (
    <div className="App">
    </div>
  );
}
Вход в полноэкранный режим Выход из полноэкранного режима

В приведенном выше примере аналитика утешается при каждом изменении routeUrl или userName. Но нам это не нужно, мы хотим, чтобы аналитика успокаивалась только при изменении routeUrl, а не userName.

Зачем вам регистрировать аналитику при изменении userName?

UseCallback снова не решит эту проблему из-за массива зависимостей. Нам нужно что-то, что не имеет массива зависимостей и всегда имеет доступ к обновленным состояниям.

Что ж, похоже, что новый хук скоро присоединится к списку основных хуков React.

Решение: useEvent снова приходит на помощь.

После выхода useEvent решение будет выглядеть примерно так, как показано ниже.

import { useState, useEffect, useEvent } from "react";

export default function App() {
  const [routeUrl, setRouteUrl] = useState("/home");
  const [userName, setUserName] = useState("Swastik");

  const logAnalytics = useEvent((routeUrl) => {
    console.log(`Route changed by ${userName} to ${routeUrl}`);
  });

  useEffect(() => {
    logAnalytics(routeUrl);
  }, [logAnalytics, routeUrl]);

  return (
    <div className="App">
    </div>
  );
}
Вход в полноэкранный режим Выход из полноэкранного режима

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

Я также веду еженедельную рассылку новостей и совсем недавно запустил канал на youtube.

Пожалуйста, поддержите меня.

Спасибо!

Оцените статью
Procodings.ru
Добавить комментарий