[React] 17. useEffect

서회정's avatar
Mar 02, 2026
[React] 17. useEffect

1. useEffect란

💡
리액트 컴퍼넌트의 사이드 이펙트를 제어하는 새로운 리액트 훅이다.
 

✅ 사이드 이펙트란?

 
여기서 말하는 리액트의 사이드 이펙트
부수적인 효과나 파생되는 효과로 설명할 수 있다.
 
notion image
 
즉, useEffect는 컴퍼넌트의 동작에 따라 파생되는 여러 효과를
제어하는 훅이다.
 
notion image
 
notion image
 

2. useEffect 실습

 
실습은 저번 시간에 만들어두었던 카운트앱을 통해 진행해보자.
 
import "./App.css"; import Controller from "./components/Controller"; import Viewer from "./components/Viewer"; import { useState } from "react"; function App() { const [count, setCount] = useState(0); const onClickButton = (value) => { setCount(count + value); }; return ( <div className="App"> <h1>Simple Counter</h1> <section> <Viewer count={count} /> </section> <section> <Controller onClickButton={onClickButton} /> </section> </div> ); } export default App;
 
먼저, useEffect라는 리액트 훅을 사용하기 위해서는
StateRef 훅을 사용할 때와 마찬가지로 import를 먼저 해주자.
 
import { useState, useEffect } from "react";
 
컴퍼넌트 내부에서 값이 변경되었을 때 어떠한 동작을
수행할 수 있도록 하는 것이 목표이다.
 
먼저 useEffect를 사용할 때의 문법은 다음과 같다.
 
useEffect(()=>{},[])
 
useEffect의 첫 번째 인수로 콜백 함수를 넣고,
두 번째 인수로 배열을 넣는다.
 
이렇게 작성하면 두 번째 인수로 전달된 배열에 들어가 있는 값이
변경되면 첫 번째 인수로 전달된 콜백 함수를 실행시키게 된다.
 
그래서 우리는 기존에 만들어둔 카운터 프로그램에서 count값이
변경될 때 콜백 함수를 실행시킬 것이다.
 
배열 안에 count를 넣고 콜백 함수 안에 콘솔 출력 코드를 입력해
count값의 변경에 따라 함수가 잘 실행 되는 지 확인해보자.
 
useEffect(()=>{ console.log(`count : ${count}`) },[count])
 
count값이 변경됨에 따라 콘솔에 출력한 count값을
출력하는 코드가 잘 실행되고 있는 것을 확인할 수 있다.
 
notion image
 
useEffect는 두 번째 인수로 전달된 배열에 무엇을 넣는 지에 따라
다르게 동작하기 때문에 해당하는 배열을
의존성 배열 (dependency array = deps) 이라 부른다.
 
이러한 deps에는 여러가지 값을 넣을 수 있다.
다른 값도 넣어보기 위해 사용자의 입력을 받아오는 input태그를
추가하고 그 값의 상태를 관리할 수 있는 state도 만들어보자.
 
onChange 이벤트로 단순히 input안의 값이 변경될 때
변경된 값을 input이라는 변수에 저장하고자 하는 코드다.
 
import "./App.css"; import Controller from "./components/Controller"; import Viewer from "./components/Viewer"; import { useState, useEffect } from "react"; function App() { const [count, setCount] = useState(0); const [input, setInput] = useState(""); useEffect(()=>{ console.log(`count: ${count}`) },[count]) const onClickButton = (value) => { setCount(count + value); }; return ( <div className="App"> <h1>Simple Counter</h1> <section> <input value={input} onChange={(e)=>{ setInput(e.target.value) }}></input> </section> <section> <Viewer count={count} /> </section> <section> <Controller onClickButton={onClickButton} /> </section> </div> ); } export default App;
 
만들어진 폼에 값을 입력했을 때,
아까 만들어 둔 useEffect의 콜백함수는 실행되지 않는다.
deps안에 count만 들어가 있기 때문이다.
 
그래서 폼 안의 입력 값이 바뀔 때에도 해당하는
콜백 함수를 실행시키고자 한다면 deps에 input을 추가해 주면 된다.
 
notion image
 
useEffect(()=>{ console.log(`count: ${count} / input: ${input}`) },[count, input])
 
잘 출력됨!
 
notion image
 

✅ 이거 State만으로도 구현되는거 아닌가?

 
라고 생각할 수 있다.
기존에 만들어두었던 이벤트 핸들러에 해당 코드를 출력해보면
안되는 이유를 바로 알 수 있다.
 
const onClickButton = (value) => { setCount(count + value); // 추가된 코드 console.log(`count: ${count}`) };
console.log(`count: ${count}`) 코드를 추가하고
해당 버튼을 클릭했을 때 콘솔에는 한 스텝 늦게 결과가
출력되는 것을 확인할 수 있다.
 
콘솔이 출력된 시점에는 setCount라는 함수가 호출은 되었지만
실제로 완료된 상태가 아니기 때문에 클릭을 하기 전의 상태가 출력되는 것이다.
 
리액트 State는 비동기로 업데이트 되기 때문인데,
따라서 리액트의 라이프 사이클의 정확한 시점에 맞추어
동작을 실행하고자 한다면 useEffect를 사용하여야 한다.
Share article

clubnerdy