Хук useEffect в ReactJS


Введение

Итак, когда я был маленьким, моя мама сказала мне.
«Новый API хуков React действительно крут, хук useEffect заменил componentDidMount & componentDidUpdate из API классов».

Я хотел расспросить ее об этом подробнее, но она была занята оптимизацией своего компонента React, который перерисовывался несколько раз.

Когда я стал старше, я узнал больше о React & эти хуки API, и сегодня я попытаюсь объяснить ВАМ то, что моя мама не объяснила МНЕ & вероятно, ваша мама тоже не объяснила — useEffect.

Настройка

Итак, здесь я создал React приложение в codesandbox на моем браузере.

Ага! В моем веб-браузере!

Вот ссылка, взаимодействуйте с ним сами!

Для тех из вас, ленивых, кто не хочет никуда идти, вот код 🫠

// App.js

import { useEffect, useState } from "react";

export default function App() {
  const [counter, setCounter] = useState(0);

  useEffect(() => {
    console.log(counter);
  });

  return (
    <div style={{ width: "100%", textAlign: "center" }}>
      <h3>{counter}</h3>
      <button onClick={() => setCounter((prevValue) => prevValue + 1)}>
        Increment
      </button>
    </div>
  );
}

Войти в полноэкранный режим Выйти из полноэкранного режима

Просто?

Всего 1 переменная состояния counter, которая увеличивается при каждом нажатии кнопки setCounter, также useEffect с console.log(counter) в теле функции, ничего kubernetes!

Код

Давайте теперь сосредоточимся на useEffect, определенном здесь

useEffect(() => {
  console.log(counter);
});
Вход в полноэкранный режим Выйти из полноэкранного режима

Как видно из кода, хук принимает функцию, которую он будет внутренне вызывать в «определенные моменты». Этими «моментами» могут быть повторный рендеринг компонента, начальный монтаж компонента или любой вызов обновления состояния, который заставляет компонент, конечно же, повторно рендериться.

После выполнения этого кода я нажимаю кнопку увеличения 3 раза & вот какие консольные журналы я получаю:

🤔 Хм… похоже, что этот конкретный useEffect выполнялся в этих случаях:

  1. Когда компонент впервые монтируется (печатается «0» в консоль)
  2. Когда я нажимаю кнопку увеличения или, короче говоря, происходит обновление состояния.

Теперь давайте изменим useEffect на следующее:

useEffect(() => {
  console.log(counter);
}, []);
Войти в полноэкранный режим Выйти из полноэкранного режима

Обратите внимание, что теперь мы передаем пустой массив «[]» (также известный как Dependency Array) в качестве второго аргумента хука useEffect.

Запустив код снова, я нажимаю кнопку инкремента 3 раза & вот какой консольный лог я получаю:

Итак, на этот раз useEffect выполнялся только во время монтирования компонента & НЕ во время обновления состояния… ИНТЕРЕСНО! 🧐

Теперь, еще раз! Давайте еще раз отредактируем код, потерпите 🙂

//App.js

import { useEffect, useState } from "react";

export default function App() {

  const [counter, setCounter] = useState(0);
  const [anotherCounter, setAnotherCounter] = useState(0)

  useEffect(() => {
    console.log("COUNTER VALUE", counter);
  }, [counter]);

  return (
    <div style={{ width: "100%", textAlign: "center" }}>

      <h3>{counter}</h3>
      <button onClick={() => setCounter((prevValue) => prevValue + 1)}>
        Increment
      </button>

      <br /><br />

      <h3>{anotherCounter}</h3>
      <button onClick={() => setAnotherCounter((prevValue) => prevValue + 1)}>
        Random State Update
      </button>

    </div>
  );
}

Вход в полноэкранный режим Выход из полноэкранного режима

Хорошо, итак… Я сделал здесь 3 вещи:

  1. Добавить переменную состояния counter в ранее оставленный пустой массив
  2. Добавьте еще одну переменную состояния & назвав ее anotherCounter.
  3. Добавьте JSX для отображения & инкремента переменной anotherCounter.

Теперь я запущу приложение & нажму кнопку «Increment» 3 раза & кнопку «Random State Update» 2 раза и вот какие консольные логи я получил

Оооо! Итак, теперь хук useEffect запускает нашу функцию ИЗБРАННО при изменении состояния counter, а не при изменении состояния anotherCounter, хотя setAnotherCounter заставляет компонент перерисовывать и обновлять anotherCounter в UI.

Теперь вы, вероятно, в какой-то степени поняли, что означал этот «пустой массив ( [] )»…

ОТЛИЧНО!

Давайте вспомним, что может сделать useEffect при правильном написании!

  1. Когда массив зависимостей остается пустым, useEffect будет запускать функцию обратного вызова (определенную нами) ТОЛЬКО ОДИН раз сразу после того, как компонент отрисует UI. (эквивалентно componentDidMount в классе компонентов)
useEffect(() => {
  /*
    Here, state initialization logic can be added
    OR, fetch requests to Backend servers can be made for data-fetching
    As this is only running once, you're not bombarding your server

  */
}, [])
Вход в полноэкранный режим Выход из полноэкранного режима
  1. При наличии переменной(ых) состояния, заданных в массиве зависимостей, useEffect будет запущен, когда компонент впервые смонтирует & также будет запущен при изменении заданных переменных состояния
useEffect(() => {
    // ...
}, [...dependencies])
Вход в полноэкранный режим Выйти из полноэкранного режима
  1. Если в качестве второго аргумента не определен массив зависимостей, хук будет вызывать нашу функцию при КАЖДОМ последующем повторном рендеринге компонента
useEffect(() => {
  // I don't prefer this but yeah! it's there if you want to use it!
})
Войти в полноэкранный режим Выход из полноэкранного режима

Аааа… вот и все!
Ставьте лайк, если вам понравился этот пост 🙃

А если вам понравилось? Вы должны следовать за мной в Twitter 😉

Обратная связь очень ценится! 🤗



Встретимся в другой день с другим постом ⚡️

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