📢 어렵고 정석적인 개념 설명보다는 저같은 초보자도 이해하기 쉽게 정리하는 것을 원칙으로 포스팅하고 있습니다. 😄

[React] 리액트 생명주기를 제어하는 useEffect()

What

인간에게 탄생부터 죽음까지 이르는 생명 주기가 있듯이 리액트의 컴포넌트에도 탄생-변화-죽음이라는 생명 주기가 있다. 컴포넌트가 화면에 나타나는 것을 Mount라 하고 업데이트(re-render)되는 것을 Update, 화면에서 사라지는 것을 UnMount라고 한다. 각 단계마다 컴포넌트를 제어하는 방법이 바로 useEffect이다.

 

How

Mount(탄생)

// 컴포넌트가 화면에 생성되었을 때 실행

useEffect(() => {
    console.log('Mount')
}, [])

useEffect()는 기본적으로 콜백 함수를 가지며, deps라고 하는 의존성 배열을 가진다.

deps를 빈 배열로 두면 컴포넌트의 탄생인 Mount일 때 한 번 console.log를 실행한다.

 

Update(변화)

// 화면이 re-render 될 때마다 실행 (컴포넌트가 업데이트될 때마다)

useEffect(() => {
    console.log('Mount')
})

컴포넌트의 요소가 변화하며 화면이 리렌더될 때마다 console.log를 실행한다.

Update의 경우 useEffect()에 deps를 넣지 않으면 된다. 

 

// 컴포넌트의 특정 요소가 변할 때만 실행

const [count, setCount] = useState(0);
const countUp = () => {
    setCount(count + 1);
}

useEffect(() => {
    console.log("count가 변경되었습니다.");
}, [count])

컴포넌트 전체 리렌더가 아닌 특정 요소만 변화했을 때 그 변화만을 감지하고 useEffect()를 실행하는 방법도 있다.

위 코드의 경우 count가 변할 때마다 console.log가 실행된다. deps안에 감지할 특정 대상을 넣어주면 된다.

하지만, 위의 2개의 useEffect의 경우 한 가지 부작용이 있다. 바로 컴포넌트의 Update 뿐만 아닌 Mount도 포함한다는 것이다. 따라서 처음 렌더링될 때 Mount와 Update가 동시에 실행된다.

 

// Mount를 포함하지 않는 Update

const mounted = useRef(false);

useEffect(() => {
    if (!mounted.current){
        mounted.current = true;
    } else {
        alert('count가 업데이트 되었습니다.')
    }
}, [count])

위와 같이 작성하면 Mount가 되어도 alert 창이 뜨지 않는다. 오로지 count가 변할 때만 alert 창이 뜬다.

 

UnMount(죽음)

// 컴포넌트가 화면에서 사라졌을 때 실행

useEffect(() => {
    console.log('Mount'); // Mount와 같이 사용 가능
    return () => {
        console.log('UnMount');
    }
}, [])

UnMount는 Mount와 동시 사용 가능하다. 빈 배열의 deps를 두고 return 뒤에 함수를 넣는 CleanUp 함수를 통해 컴포넌트가 화면에서 사라졌을 때 console.log가 실행되게 할 수 있다.

 

1. Mount는 컴포넌트가 화면에 생성될 때, deps는 빈 배열
2. Update는 컴포넌트가 변경될 때, deps는 없거나 특정 요소를 담음
3. UnMount는 컴포넌트가 화면에서 사라졌을 때, deps는 빈 배열, CleanUp 함수 사용