React에서 함수 컴포넌트의 rendering이란 state, props를 기반으로 UI 요소를 그려내는 행위이다.
(state, props) ⇒ UI
Side Effect
부작용, 부수 효과라고도 부르는 Side Effect는 일상 생활의 맥락에서는 부정적인 의미로 사용되는 경우가 많지만 프로그래밍 측면에서의 Side Effect는 단순히 부정적인 의미로만 사용되지 않는다.
아래처럼 input - output 이외의 다른 값을 조작한다면, 이 함수에는 Side Effect(부수 효과) 가 있다고 표현한다.
let count = 0
function helloWord(name) { // Input
count = count + 1 // Side Effect
return `${name}님 안녕하세요!` // Output
}
helloWorld() 라는 함수는 이름을 받아 인삿말을 리턴하는 함수인데 이 함수는 단순히 input과 output만 존재하는 함수가 아닙니다. 실행하는 중간에 함수 외부 세계에 있는 count라는 변수를 조작한다. 이는 함수의 결과값 이외의 다른 상태를 변경시키는 행위에 해당하므로 Side Effect 가 있다라고 할 수 있다.
하지만 이런 side Effect들을 함수의 body 자리(render)에서 실행시킬 시에 state,props가 변화가 있을때 마다 body에 선언한 side Effect 함수로직이 렌더링 될때마다 쓸데없이 실행된다는 뜻이므로 성능에 악영향을 준다. 이를 보완하기 위하여 리액트에선 useEffect Hook을 제공합니다.
useEffect
정의: useEffect에 전달된 함수는 화면에 렌더링이 완료된 후에 수행되게 될 것. React의 순수한 함수적인 세계에서 명령적인 세계로의 탈출구로 생각하세요.( "순수한 세계"란 렌더링(Input → Output)을 뜻하고, 렌더링 이외에 일으켜야 하는 Side Effect를 일으킬 탈출구로 useEffect를 사용하라는 의미)
useEffect는 Side Effect를 렌더링 이후에 발생시킨다. => useEffect가 수행되는 시점에 이미 DOM이 업데이트된다.
약 Side Effect 이후 업데이트 된 정보가 있어 새롭게 화면이 그려져야 할 경우(state, props의 업데이트) 새롭게 렌더링을 일으킵니다.
import { useEffect } from 'react';
function helloWorld({ name }) { // Input
**useEffect(() => {
// Good!
document.title = `${name}님 안녕하세요!`; // Side Effect
}, [name]);**
return <div>{`${name}님 안녕하세요!`}</div>; // Output
}
함수 컴포넌트는 최신 state와 props를 반영한 화면을 리턴하게 된다. Effect 타이밍은 의존성 배열(Dependancy Array)를 [] 통해 표현하게 된다.
의존성배열 사용예시
import { useEffect } from "react"
useEffect( 실행시킬 동작, [ 타이밍 ] )
//document.addEventListener("타이밍", 실행시킬 동작)
// 매 렌더링마다 Side Effect가 실행되어야 하는 경우
useEffect(() => {
// Side Effect
})
// Side Effect가 첫 번째 렌더링 이후 한번 실행 되고,
// 이후 특정 값의 업데이트를 감지했을 때마다 실행되어야 하는 경우
useEffect(() => {
// Side Effect
}, [value])
// Side Effect가 첫 번째 렌더링 이후 한번 실행 되고,
// 이후 어떤 값의 업데이트도 감지하지 않도록 해야 하는 경우
useEffect(() => {
// Side Effect
}, [])