Хук useEffect - один из самых мощных и универсальных инструментов в арсенале разработчика React. Он позволяет вам управлять побочными эффектами в ваших функциональных компонентах и поддерживать чистоту, организованность и производительность вашего кода.
В этом блоге мы подробно рассмотрим хук useEffect, охватывая все, начиная с основ его работы и заканчивая более сложными темами, такими как работа с зависимостями и очистка эффектов.
Рекомендуется прочитать предыдущий блог о useState before reading this one, так как он обеспечивает отличную основу для понимания того, как работает хук useEffect в отношении состояния. Мы также предоставим реальные примеры и объяснения, чтобы помочь вам освоить этот важный инструмент и улучшить производительность ваших React-приложений.
Сначала нужно понять, что такое побочные эффекты. Можно сказать, что если функция изменяет какое-то состояние вне локального окружения, то можно сказать, что это побочный эффект.
Примерами таких побочных эффектов являются,
Итак, useEffect или просто Effect полезен для обработки таких побочных эффектов. Он запускается в конце рендеринга как его право синхронизировать наш компонент с внешней системой.
Использовать UseEffect следующим образом:
useEffect(()=>{ //Run side effects here }, [ //This is a dependency array //This is optional ])
Давайте рассмотрим один пример:
Это простой компонент счетчика, мы увеличиваем счетчик при каждом нажатии на кнопку. После каждого нажатия кнопки useEffect будет перерисовывать компонент.
const Useeffect = () => { const [counter, setCounter] = useState(0); useEffect(()=>{ console.info("inside useEffect") //This will rerender after each button click. }) const handleOnClick=()=>{ console.info("Button Clicked") setCounter(counter+1); } return ( <div> <button onClick = {handleOnClick} >Click me!</button> <h3>{counter}</h3> </div> ) }
Теперь мы хотим добавить функциональность для изменения цвета фона документа только в этом компоненте. Код будет выглядеть следующим образом:
Цвет фона был установлен на белый. Когда пользователь вводит цвет, цвет фона меняется. Однако даже когда счетчик увеличивается, хук useEffect все равно запускается, и это потому, что мы не указали массив зависимостей для хука.
const Example = () => { const [color, setColor] = useState("white"); const [counter, setCounter] = useState(0); useEffect(() => { console.info("inside useEffect") document.body.style.backgroundColor = color; }); const handleOnClick = (e) => { e.preventDefault() setCounter(counter+1) }; console.info("rendering") return ( <div> <input type="text" onChange = {(e) => { setColor(e.target.value); }} name="color" value = {color} /> <br style = {{margin:20}}/> <button onClick = {handleOnClick}>Click me!</button> <label>{counter}</label> </div> ); };
Массив зависимостей - это список переменных состояния или функций, от которых зависит хук useEffect. При изменении этих значений срабатывает функция обратного вызова useEffect. Используя массив зависимостей, мы можем предотвратить чрезмерный повторный рендеринг компонентов, что делает код более эффективным.
useEffect(callback, dependency array)
Теперь давайте добавим массив зависимостей в приведенный выше код:
const Example = () => { const [color, setColor] = useState("white"); const [counter, setCounter] = useState(0); //This is useEffect for changes the color of document useEffect(() => { console.info("inside useEffect1") document.body.style.backgroundColor = color; },[color]); //Here in the dependency array we have added the color state varaible //Whenever the color state changes then only this useEffect will run //In this useEffect we did not provide any depencency array useEffect(() => { console.info("inside useEffect2") }); const handleOnClick = (e) => { e.preventDefault() setCounter(counter+1) }; console.info("rendering") return ( <div> <input type="text" onChange = {(e) => { setColor(e.target.value); }} name="color" value = {color} /> <br style = {{margin:20}}/> <button onClick = {handleOnClick}>Click me!</button> <label>{counter}</label> </div> ); };
Как мы видим, только 2-й useEffect внутри компонента будет вызываться при нажатии на кнопку, а 1-й useEffect - при изменении входных данных, т.е. при изменении состояния цвета.
Но что если компонент не зависит ни от какого состояния, мы передадим пустой массив в качестве массива зависимостей. В этом случае useEffect будет выполняться только один раз. Примером может быть получение данных из API .
useEffect(() => { fetch("https://jsonplaceholder.typicode.com/users") }, []);
Будет получать данные из API , используя только один вызов.
Важно отметить, что хук useEffect по умолчанию будет выполняться при каждом рендере. Например, если данные из API извлекаются в то время, как пользователь переходит на другую страницу, извлечение данных будет продолжаться, даже если в них больше нет необходимости. Нам нужно прервать ее. Это можно сделать с помощью AbortController .
Согласно документации React, React будет выполнять очистку по мере размонтирования компонента. Но useEffects запускается для каждого рендера, а не только один раз. Поэтому React также очищает эффекты от предыдущего рендера, прежде чем запускать их в следующий раз.
Код будет выглядеть следующим образом:
useEffect(() => { effect return () => { cleanup } }, [input])
Рассмотрим на примере, как реализовать функцию очистки.
useEffect(() => { const controller = new AbortController(); //AbortController is a simple object //that generates an 'abort' event on its 'signal' property //when the abort() method is called. const signal = controller.signal; //We can pass this sinal as a option to the 'fetch', //it will listen to it and we can abort the fetch request fetch("https://jsonplaceholder.typicode.com/users", { signal }) .then((response) => response.json()) .then((response) => { // handle success console.info(response); }) .catch((err) => { if (err.name === 'AbortError') { console.info('successfully aborted'); } else { // handle error } }); return () => { // cancel the request before component unmounts controller.abort(); }; }, []);
Мы переходим на другую страницу, то функция abort будет вызвана до того, как компонент будет размонтирован. В результате состояние не будет обновлено и не возникнет ошибка.
Вот и все о useEffect. Если вы не читали блог о useState, пожалуйста, прочитайте его, нажав здесь . В следующем блоге мы рассмотрим useContext.
Спасибо, что прочитали эту статью, надеюсь, она помогла вам понять, как эффективно использовать хук useEffect.
20.08.2023 18:21
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в 2023-2024 годах? Или это полная лажа?".
20.08.2023 17:46
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
19.08.2023 18:39
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в частности, магию поплавков и гибкость flexbox.
19.08.2023 17:22
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для чтения благодаря своей простоте. Кроме того, мы всегда хотим проверить самые последние возможности в наших проектах!
18.08.2023 20:33
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий их языку и культуре.
14.08.2023 14:49
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип предназначен для представления неделимого значения.