Порівняння хуків отримання даних у React

Хуки React — це потужний спосіб керувати побічними ефектами в компонентах React. Три найпоширеніші хуки для обробки побічних ефектів: useEffect, useLayoutEffect і useEffectEvent. Кожен гачок має свій унікальний варіант використання, тому вибір правильного для роботи є важливим.

Хук useEffect

Хук useEffect — це фундаментальний хук у React, який дозволяє виконувати побічні ефекти, такі як маніпуляції DOM, асинхронні операції та вибірка даних у функціональних компонентах. Цей хук є функцією, яка приймає два аргументи, функцію ефекту та масив залежностей.

Функція ефекту містить код, який виконує побічний ефект, а масив залежностей визначає, коли виконується функція ефекту. Якщо масив залежностей порожній, функція ефекту запускається лише один раз під час початкового відтворення компонента. В іншому випадку функція ефекту запускається щоразу, коли змінюється будь-яке значення в масиві залежностей.

Ось приклад використання хука useEffect для отримання даних:

 import React from "react";

function App() {
  const [data, setData] = React.useState([]);

  React.useEffect(() => {
    fetch("<https://jsonplaceholder.typicode.com/posts>")
      .then((response) => response.json())
      .then((data) => setData(data));
  }, []);

  return (
    <div className="app">
      {data.map((item) => (
        <div key={item.id}>{item.title}</div>
      ))}
    </div>
  );
}

export default App;

Цей код демонструє компонент програми, який отримує дані із зовнішнього API за допомогою хука useEffect. Функція ефекту useEffect отримує зразки даних з JSONPlaceholder API. Потім він аналізує відповідь JSON і встановлює отримані дані в стан даних.

За допомогою стану даних компонент App відображає властивість title кожного елемента в стані.

Характеристики використання Effect Hook

  • Зручний для асинхронності: підтримує асинхронні операції, що робить його зручним для отримання даних.
  • Запускається після відтворення: хук useEffect виконує свої ефекти після того, як програма відтворить компонент, гарантуючи, що хук не блокує інтерфейс користувача.
  • Очищення: забезпечує інтегрований спосіб очищення шляхом повернення функції. Це може бути особливо корисно при роботі зі слухачами або підписками.
  Як залишатися активним і здоровим на природі за допомогою геокешинга

Хук useLayoutEffect

Хук useLayoutEffect схожий на хук useEffect, але виконується синхронно після всіх мутацій DOM. Це означає, що він запускається до того, як браузер зможе розфарбувати екран, що робить його придатним для завдань, які вимагають точного контролю над макетом і стилями DOM, наприклад вимірювання розміру елемента, зміна розміру елемента або анімація його положення.

Нижче наведено приклад того, як використовувати хук useLayoutEffect для зміни ширини елемента кнопки:

 import React from "react";

function App() {
  const button = React.useRef();

  React.useLayoutEffect(() => {
    const { width } = button.current.getBoundingClientRect();

    button.current.style.width = `${width + 12}px`;
  }, []);

  return (
    <div className="app">
      <button ref={button}>Click Me</button>
    </div>
  );
}

export default App;

Наведений вище блок коду збільшує ширину елемента кнопки на 12 пікселів за допомогою хука useLayoutEffect. Це гарантує, що ширина кнопки збільшиться до того, як кнопка відобразиться на екрані.

Характеристики хука useLayoutEffect

  • Синхронний: він виконується синхронно, потенційно блокуючи інтерфейс користувача, якщо операція в ньому важка.
  • Читання/запис DOM: найкраще підходить для читання та запису безпосередньо в DOM, особливо якщо вам потрібні зміни перед перемальовуванням браузера.

Хук useEffectEvent

Хук useEffectEvent — це хук React, який вирішує проблеми залежностей хука useEffect. Якщо ви знайомі з useEffect, ви знаєте, що його масив залежностей може бути складним. Іноді в масив залежностей потрібно додати більше значень, які є вкрай необхідними.

  Розвивайте продажі свого бізнесу за допомогою Pipedrive CRM

Наприклад:

 import React from "react";

function App() {
  const connect = (url) => {
    
  };

  const logConnection = (message, loginOptions) => {
    
  };

  const onConnected = (url, loginOptions) => {
    logConnection(`Connected to ${url}`, loginOptions);
  };

  React.useEffect(() => {
    const device = connect(url);
    device.onConnected(() => {
      onConnected(url);
    });

    return () => {
      device.disconnect();
    };
  }, [url, onConnected]);

  return <div></div>;
}

export default App;

Цей код демонструє компонент програми, який керує підключенням до зовнішньої служби. Функція підключення підключається до вказаної URL-адреси, а функція logConnection реєструє деталі підключення. Нарешті, функція onConnected викликає функцію logConnection для реєстрації повідомлення про успішне підключення, коли пристрій підключається.

Хук useEffect викликає функцію підключення, а потім налаштовує функцію зворотного виклику onConnected для виконання, коли пристрій запускає подію onConnected. Цей зворотній виклик реєструє повідомлення про підключення. Він повертає функцію очищення, яка активується під час демонтування компонента. Ця функція очищення відповідає за відключення пристрою.

Масив залежностей містить змінну url і функцію onConnected. Компонент App створюватиме функцію onConnected для кожного рендера. Це спричинить запуск функції useEffect у циклі, який продовжуватиме повторне відтворення компонента програми.

Існує кілька способів вирішення проблеми циклу useEffect. Тим не менш, найефективніший спосіб зробити це без додавання непотрібних значень до вашого масиву залежностей — хук useEffectEvent.

 import React from "react";

function App() {
  const connect = (url) => {
    
  };

  const logConnection = (message, loginOptions) => {
    
  };

  const onConnected = React.useEffectEvent((url, loginOptions) => {
    logConnection(`Connected to ${url}`, loginOptions);
  });

  React.useEffect(() => {
    const device = connect(url);
    device.onConnected(() => {
      onConnected(url);
    });

    return () => {
      device.disconnect();
    };
  }, [url]);

  return <div></div>;
}
export default App;

Обгортаючи функцію onConnected хуком useEffectEvent, хук useEffectEvent завжди може читати останні значення параметрів повідомлення та loginOptions перед передачею їх хуку useEffect. Це означає, що useEffect не повинен покладатися на функцію onConnected або передані їй значення.

  12 виправлень для помилок Civilization 5, які не запускаються

Хук useEffectEvent корисний, коли ви хочете, щоб ваш useEffect залежав від певного значення, навіть якщо ефект ініціює подію, яка вимагає інших значень, які ви не бажаєте використовувати як залежності в useEffect.

Характеристики хука useEffectEvent

  • Він найкраще підходить для побічних ефектів, спричинених подіями.
  • Хук useEffectEvent не працює з обробниками подій, такими як onClick, onChange тощо.

Хук useEffectEvent все ще експериментальний і недоступний у хуках React версії 18.

Коли використовувати який гачок?

Кожен із вищевказаних хуків для отримання даних підходить для різних ситуацій:

  • Отримання даних: UseEffect є чудовим вибором.
  • Прямі маніпуляції з DOM: якщо вам потрібно внести синхронні зміни в DOM перед перемальовуванням, виберіть useLayoutEffect.
  • Полегшені операції: для операцій, які не ризикують блокувати інтерфейс користувача, ви можете вільно використовувати useEffect.
  • Побічні ефекти, керовані подіями: використовуйте хук useEffectEvent, щоб обернути події, і хук useEffect, щоб запустити побічні ефекти.

Ефективно справляйтеся з побічними ефектами

Хуки React відкривають цілий світ можливостей, і розуміння різниці між хуками useEffect, useLayoutEffect і useEffectEvent може значно вплинути на те, як ви обробляєте побічні ефекти та маніпуляції DOM. Важливо враховувати специфічні вимоги та наслідки цих хуків, щоб створити зручні для користувача програми.