Side Effect
들을 function
의 body
자리에서 실행시키면 안된다. function component
의 return
값은 UI
요소이다. state, props
의 변화가 있을 때마다 function
이 실행된다. 즉, rendering
때마다 function body
에 있는 로직이 실행된다.
rendering
과 무관한 로직이 rendering
과정에서 실행되기 때문에 rendering
자체에 영향을 줘 성능 문제가 발생할 수 있다.
function greetWithSideEffect({ name }) {
// Bad😡
document.title = `${name} hello!`; // Side Effect
return <div>{`${name} hello!`}</div>; // Output
}
React
에서는 이런 Side Effect
를 일으키기 적합한 도구로서 useEffect hook
을 사용한다.
"React의 순수한 함수적인 세계에서 명령적인 세계로의 탈출구로 생각하세요" -React 공식 문서-
여기서 "순수한 세계"란 rendering(Input-Output)
을 뜻하며, rendering
이외에 일으켜야 하는 Side Effect
를 일으킬 탈출구로 useEffect
를 사용하라는 의미이다.
useEffect
는 Side Effect
를 rendering
이후에 발생시킨다. useEffect
가 실행되는 시점에 이미 DOM
이 업데이트되었음을 보장한다는 뜻이고, Side Effect
가 rendering
에 영향을 주지 않도록 설계되었음을 의미한다.
import { useEffect } from 'react';
function greetWithSideEffect({ name }) { // Input
useEffect(() => {
// Good😁
document.title = `${name} Hello!`; // Side Effect
}, [name]);
return <div>{`${name} Hello!`}</div>; // Output
}
Side Effect
이후 업데이트 된 정보가 있어 새롭게 화면이 그려져야 할 경우 새롭게 rendering
한다. function component
는 최신 state
와 props
를 반영한 화면을 return
하게 된다. Effect
를 일으킬 타이밍은 앞서 설명했던 useEffect
의 두 번째 인자인 Dependancy Array(의존성 배열)
를 통해 표현하게 된다.
useEffect는 다음과 같은 형태로 사용한다. 두 번째 인자에 감지할 값을 배열로 넘겨주게 되면 해당 값들이 변경이 일어났을 경우에만 실행되게 할 수도 있다.
import { useEffect } from 'react';
// 사용법
useEffect( 실행시킬 동작, [타이밍] )
document.addEventListener('타이밍', 실행시킬 동작) // 추상화 한 예시
// 매 rendering 때마다 Side Effect가 실행되어야 하는 경우
useEffect(() => {
// Side Effect
})
// Side Effect가 첫 번째 rendering 이후 한번 실행되고,
// 이후 특정 값의 업데이트를 감지할 때마다 실행되어야 하는 경우
useEffect(() => {
// Side Effect
}, [타이밍])
// Side Effect가 첫 번째 rendering 이후 한번 실행되고,
// 이후 어떤 값의 업데이트도 감지하지 않도록 해야 하는 경우
useEffect(() => {
// Side Effect
}, [])