React
useEffect
useEffect Hook을 사용하면 구성 요소에서 부작용을 수행할 수 있다.
부작용의 예로는 데이터 가져오기, DOM 직접 업데이트 및 타이머가 있다.
useEffect는 두 개의 인수를 허용한다.
두 번째 인수는 선택사항이다.
useEffect(
예제
setTimeout()을 사용하여 초기 렌더링 후 1초를 카운트한다.
import { useState, useEffect } from "react"; import ReactDOM from "react-dom/client"; function Timer() { const [count, setCount] = useState(0); useEffect(() => { setTimeout(() => { setCount((count) => count + 1); }, 1000); }); return <h1>I've rendered {count} times!</h1>; } const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<Timer />);
기본 예시
예제 보기
그런데, 한 번만 세야 하는데도 계속 세고 있다.
useEffect는 모든 렌더에서 실행된다.
즉, 카운트가 변경되면 렌더가 발생하고, 그 후에 다른 효과가 발생한다.
이것은 우리가 원하는 것이 아니다.
부작용이 발생했을 때 제어할 수 있는 여러 가지 방법이 있다.
우리는 배열을 받아들이는 두 번째 매개변수를 항상 포함해야 한다.
우리는 이 배열에서 Effect를 사용하기 위해 종속변수를 선택적으로 전달할 수 있다.
예제 – 종속성 없음
useEffect(() => { //Runs on every render });
예제 – 빈 배열
useEffect(() => { //Runs only on the first render }, []);
예제 – props 또는 상태 값
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/client"; 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>; } const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<Timer />);
기본 예시
예제 보기예제
다음은 변수에 따라 달라지는 useEffect Hook의 예다.
카운트 변수가 업데이트되면 효과가 다시 실행된다.
import { useState, useEffect } from "react"; import ReactDOM from "react-dom/client"; 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> </> ); } const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<Counter />);
기본 예시
예제 보기효과 정리
일부 효과는 메모리 누출을 줄이기 위해 정리가 필요하다.
타임아웃, 구독, 이벤트 청취자 및 더 이상 필요하지 않은 기타 효과를 처리해야 한다.
우리는 use Effect 훅 끝에 리턴 기능을 포함시켜 이 작업을 수행한다.
예제
Use Effect Hook 끝에 타이머를 정리한다.
import { useState, useEffect } from "react"; import ReactDOM from "react-dom/client"; 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>; } const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<Timer />);
기본 예시
예제 보기참고
W3C School - React – React useEffect Hooks