이펙트 훅(useEffect Hook)은 컴포넌트가 렌더링 이후 수행해야 할 일을 결정한다.
여기서 렌더링 이후 수행해야 할 일은 사이드 이펙트(Side Effect)라고 하며
이펙트 훅(useEffect Hook)은 사이드 이펙트(Side Effect)를 일으키기 적절한 장소라고 볼 수 있다.
부작용, 부수 효과라고도 부르는 사이드 이펙트(Side Effect)는 프로그래밍에서는 부정적인 의미가 아니다. input(state & props) - output(UI) 이외의 다른 값을 조작하는 것을 의미한다. 아래의 예시에서 사이드 이펙트(Side Effect)를 확인할 수 있다.
let count = 0
function greetWithSideEffect(name) { // Input
count = count + 1 // Side Effect!
return `${name}님 안녕하세요!` // Output
}
위 함수 안에는 input과 output이 있다. 또한 input과 output만이 아닌 함수 결과 값 이외에 함수 외부에 존재하는 값이나 상태를 변경시키는 등의 행위 ("count = count + 1")가 있는데 이것이 바로 사이드 이펙트(Side Effect)가 되는 것이다.
대표적인 사이드 이펙트(Side Effect)로는 Data Fetching, DOM에 직접 접근(ex. Event Listener 등록), 구독(ex. setInterval)과 같은 행위들이 있다.
위에서 유즈이펙트 훅(useEffect Hook)은 컴포넌트가 렌더링 된 후의 발생한다고 말하였는데
(예외: useLayoutEffect) 이 말은 useEffect가 수행되는 시점에 이미 DOM이 업데이트되었음을 보장한다는 뜻이고, 바꿔 말하면 Side Effect가 렌더링에 영향을 주지 않도록 설계되었음을 의미한다.
function greetWithSideEffect({ name }) { // input
// Bad!
document.title = `${name}님 안녕하세요!`; // Side Effect
return <div>{`${name}님 안녕하세요!`}</div>; // Output
}
React에서는 state, props의 변화가 있을 때마다 함수가 실행되는데 이 말은 매 렌더링 때마다 함수 body에 있는 로직이 실행된다는 뜻이다. 그러므로 위와 같이 사이드 이펙트(side Effect)들을 함수의 body 자리(render)에서 실행시키면 안된다. 함수의 body 자리(render)에서 실행하게 되면 렌더링과 무관한 로직이 렌더링 과정에서 실행되기 때문에 렌더링 자체에 영향을 줘 성능 상 악영향을 끼칠 수도 있다.
# 리액트 리렌더링 조건
- state 변경이 있을 때
- 전달받은 props가 업데이트 될 때
- 부모 컴포넌트가 렌더링 될 때
- shouldComponentUpdate에서 true가 반환될 때
- forceUpdate가 실행될 때
그러므로 아래와 같이 유즈이펙트 훅(useEffect Hook)을 활용하여 작성해야 한다.
import { useEffect } from 'react';
function greetWithSideEffect({ name }) { // Input
// Good!
useEffect(() => {
document.title = `${name}님 안녕하세요!`; // Side Effect
}, [name]);
return <div>{`${name}님 안녕하세요!`}</div>; // Output
}