Реагировать Учебник

Реагировать Главная Реагировать Введение Реагировать Начать Реагировать ES6 Реагировать на визуализацию HTML Реагировать JSX Реагировать Компоненты Реагировать на класс Реагировать на реквизиты Реагировать на события Реагировать на условия Реагировать списки Реагировать на формы Реактивный маршрутизатор Реагировать на заметку Реагировать на стили CSS Реагировать на стиль Sass

Реагировать на крючки

Что такое крючок? использование состояния использованиеЭффект использованиеконтекста useRef использованиередьюсер использоватьОбратный звонок useMemo Пользовательские крючки

Упражнения по реагированию

Ответная викторина Упражнения по реагированию Сертификат реакции

Реагировать на useEffectкрючки


Хук useEffectпозволяет вам выполнять побочные эффекты в ваших компонентах.

Некоторые примеры побочных эффектов: выборка данных, прямое обновление DOM и таймеры.

useEffectпринимает два аргумента. Второй аргумент является необязательным.

useEffect(<function>, <dependency>)


Давайте использовать таймер в качестве примера.

Пример:

Используйте setTimeout()для подсчета 1 секунды после первоначального рендеринга:

import { useState, useEffect } from "react";
import ReactDOM from "react-dom";

function Timer() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    setTimeout(() => {
      setCount((count) => count + 1);
    }, 1000);
  });

  return <h1>I've rendered {count} times!</h1>;
}

ReactDOM.render(<Timer />, document.getElementById('root'));

Но ждать!! Я продолжаю считать, хотя это должно считаться только один раз!

useEffectзапускается при каждом рендере. Это означает, что при изменении счетчика происходит рендеринг, который запускает другой эффект.

Это не то, чего мы хотим. Есть несколько способов контролировать запуск побочных эффектов.

Мы всегда должны включать второй параметр, который принимает массив. При желании мы можем передать зависимости useEffectв этот массив.

1. Зависимость не прошла:

useEffect(() => {
  //Runs on every render
});

2. Пустой массив:

useEffect(() => {
  //Runs only on the first render
}, []);

3. Пропсы или значения состояния:

useEffect(() => {
  //Runs on the first render
  //And any time any dependency value changes
}, [prop, state]);

Итак, чтобы решить эту проблему, давайте запустим этот эффект только на начальном рендере.

Пример:

Запускайте эффект только на начальном рендере:

import { useState, useEffect } from "react";
import ReactDOM from "react-dom";

function Timer() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    setTimeout(() => {
      setCount((count) => count + 1);
    }, 1000);
  }, []); // <- add empty brackets here

  return <h1>I've rendered {count} times!</h1>;
}

ReactDOM.render(<Timer />, document.getElementById('root'));

Пример:

Вот пример useEffectхука, который зависит от переменной. Если countпеременная обновится, эффект запустится снова:

import { useState, useEffect } from "react";
import ReactDOM from "react-dom";

function Counter() {
  const [count, setCount] = useState(0);
  const [calculation, setCalculation] = useState(0);

  useEffect(() => {
    setCalculation(() => count * 2);
  }, [count]); // <- add the count variable here

  return (
    <>
      <p>Count: {count}</p>
      <button onClick={() => setCount((c) => c + 1)}>+</button>
      <p>Calculation: {calculation}</p>
    </>
  );
}

ReactDOM.render(<Counter />, document.getElementById('root'));

Если есть несколько зависимостей, они должны быть включены в useEffectмассив зависимостей.


w3schools CERTIFIED . 2022

Получите сертификат!

Завершите модули React, выполните упражнения, сдайте экзамен и получите сертификат w3schools!!

ЗАПИСАТЬСЯ НА 95 $

Очистка эффекта

Некоторые эффекты требуют очистки, чтобы уменьшить утечки памяти.

Тайм-ауты, подписки, прослушиватели событий и другие эффекты, которые больше не нужны, должны быть удалены.

Мы делаем это, включив функцию возврата в конце useEffectхука.

Пример:

Очистите таймер в конце useEffectхука:

import { useState, useEffect } from "react";
import ReactDOM from "react-dom";

function Timer() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    let timer = setTimeout(() => {
    setCount((count) => count + 1);
  }, 1000);

  return () => clearTimeout(timer)
  }, []);

  return <h1>I've rendered {count} times!</h1>;
}

ReactDOM.render(<Timer />, document.getElementById("root"));

Примечание. Чтобы очистить таймер, нам нужно было дать ему имя.


Проверьте себя с помощью упражнений

Упражнение:

Что вам нужно добавить ко второму аргументу useEffectхука, чтобы он работал только на первом рендере?

import { useState, useEffect } from "react";
import ReactDOM from "react-dom";

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

  useEffect(() => {
    setData(getData())
  }, );

  return <DisplayData data={data} />;
}

ReactDOM.render(<App />, document.getElementById('root'));