Синхронизируй свои компоненты с внешним миром через useEffect, освоив зависимости и очистку.
Открыть этот урок в KodokonКомпонент React вычисляет JSX из пропсов и состояния. Всё, что выходит за эти рамки - изменить заголовок документа, запустить таймер, подписаться на событие браузера, - это побочный эффект. useEffect выполняет такой код после рендера, не блокируя отображение, и заново синхронизирует его, когда меняются определённые значения.
import { useEffect } from "react";
function CartTitle({ count }) {
useEffect(() => {
document.title = `Cart (${count})`;
}, [count]);
return <p>Items: {count}</p>;
}Массив зависимостей управляет тем, как часто выполняется эффект. [count]: эффект перезапускается после каждого рендера, в котором изменился count. []: эффект выполняется только один раз, после первого рендера. Без массива: эффект перезапускается после каждого рендера, а это редко то, что тебе нужно. Золотое правило: любое значение компонента, используемое внутри эффекта, должно быть в массиве.
import { useEffect, useState } from "react";
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const id = setInterval(() => {
setSeconds((s) => s + 1);
}, 1000);
return () => clearInterval(id);
}, []);
return <p>Elapsed: {seconds} s</p>;
}Функция, возвращаемая эффектом, - это функция очистки. React вызывает её перед каждым новым запуском эффекта, а затем последний раз при размонтировании компонента. Именно она предотвращает утечки: осиротевшие таймеры, накопившиеся слушатели, подписки, которые никогда не отменяются. Каждый эффект, который что-то «открывает», обязан это закрыть.
useEffect(() => {
function onResize() {
setWidth(window.innerWidth);
}
window.addEventListener("resize", onResize);
return () => {
window.removeEventListener("resize", onResize);
};
}, []);useEffect(fn, []) когда выполняется функция fn?userId, но его массив зависимостей - []. В чём проблема?