Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое useEffect
useEffect — это React хук, который позволяет выполнять побочные эффекты (side effects) в функциональных компонентах. Побочные эффекты включают загрузку данных, подписки, установку таймеров, работу с DOM и другие операции, которые нельзя выполнить во время рендера.
Базовый синтаксис
useEffect(() => {
// Код, который выполняется ПОСЛЕ каждого рендера
console.log('Компонент отрендерился');
});
Код внутри useEffect выполняется ПОСЛЕ того, как компонент отрисован на экране.
Способы затриггерить useEffect
1. Без массива зависимостей (выполняется после каждого рендера)
function Component() {
useEffect(() => {
console.log('Выполняется после КАЖДОГО рендера!');
});
return <div>Hello</div>;
}
Этот вариант может привести к бесконечным циклам, обычно избегают.
2. С пустым массивом зависимостей (выполняется только при монтировании)
function Component() {
useEffect(() => {
console.log('Выполняется ОДИН РАЗ при монтировании компонента');
return () => {
console.log('Очистка при размонтировании');
};
}, []);
return <div>Hello</div>;
}
Самый распространённый вариант для загрузки данных при инициализации.
3. С массивом зависимостей (выполняется при изменении зависимостей)
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
console.log(`Загружаем пользователя ${userId}`);
fetch(`/api/users/${userId}`)
.then(res => res.json())
.then(data => setUser(data));
}, [userId]);
return <div>{user?.name}</div>;
}
Эффект запускается при изменении userId.
Практические примеры
Загрузка данных
function PostList() {
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchPosts = async () => {
try {
const response = await fetch('/api/posts');
const data = await response.json();
setPosts(data);
} catch (error) {
console.error('Ошибка загрузки:', error);
} finally {
setLoading(false);
}
};
fetchPosts();
}, []);
if (loading) return <div>Загрузка...</div>;
return <ul>{posts.map(p => <li key={p.id}>{p.title}</li>)}</ul>;
}
Подписка на событие
function WindowResizer() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
return <div>Ширина окна: {width}px</div>;
}
Следование за переменной
function SearchUsers({ searchTerm }) {
const [results, setResults] = useState([]);
useEffect(() => {
if (!searchTerm) {
setResults([]);
return;
}
const timer = setTimeout(() => {
fetch(`/api/search?q=${searchTerm}`)
.then(res => res.json())
.then(data => setResults(data));
}, 300);
return () => clearTimeout(timer);
}, [searchTerm]);
return <ul>{results.map(u => <li key={u.id}>{u.name}</li>)}</ul>;
}
Множественные зависимости
function Chart({ userId, year, month }) {
const [data, setData] = useState(null);
useEffect(() => {
fetch(`/api/stats/${userId}/${year}/${month}`)
.then(res => res.json())
.then(data => setData(data));
}, [userId, year, month]);
return <div>{data && <ChartComponent data={data} />}</div>;
}
Распространённые ошибки
Забытая зависимость (infinite loop)
function BadComponent() {
const [count, setCount] = useState(0);
useEffect(() => {
setCount(count + 1);
}, []);
}
function GoodComponent() {
const [count, setCount] = useState(0);
useEffect(() => {
setCount(c => c + 1);
}, []);
}
Лишние пересчёты
function BadComponent() {
const options = { page: 1 };
useEffect(() => {
fetch('/api/data', options);
}, [options]);
}
function GoodComponent() {
useEffect(() => {
fetch('/api/data', { page: 1 });
}, []);
}
Выводы
useEffect срабатывает ПОСЛЕ рендера компонента. Массив зависимостей контролирует, когда срабатит эффект: пустой массив [] означает срабатит один раз при монтировании (самый частый вариант), массив с зависимостями [dep1, dep2] срабатит при их изменении. Функция очистки в return удалит слушатели и таймеры при размонтировании. Правильный массив зависимостей критичен для избежания бесконечных циклов и утечек памяти.