[React] useEffect

์งฑ์ซ‘ยท2021๋…„ 12์›” 7์ผ
0

๐Ÿšถ๐Ÿปโ€โ™‚๏ธ Rendering in React

React์—์„œ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์˜ rendering์ด๋ž€, state, props๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ UI์š”์†Œ๋ฅผ ๊ทธ๋ ค๋‚ด๋Š” ํ–‰์œ„๋ฅผ ๋งํ•œ๋‹ค. ๋žœ๋”๋ง์˜ ๊ฒฐ๊ณผ๋ฌผ์€ UI์š”์†Œ ์ฆ‰, ํ™”๋ฉด์— JSX๋ฌธ๋ฒ•์œผ๋กœ ๋ฌด์—‡์ด ๋‚˜ํƒ€๋‚ ์ง€๋ฅผ ์ ์–ด๋‘” ์ปดํฌ๋„ŒํŠธ๋“ค์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋žœ๋”๋ง ๊ฒฐ๊ณผ๋ฌผ์— ์˜ํ–ฅ์„ ์ฃผ๋Š” ์š”์†Œ๋Š” state์™€ props์ด๋‹ค.
์ด๋ฅผ ๋‹ฌ๋ฆฌ ํ‘œํ˜„ํ•˜์ž๋ฉด (state, props) = UI ๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ input(state&props) ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ output(UI)์„ ํ‘œํ˜„ํ•˜๋Š” ํ•จ์ˆ˜(function)์™€๋„ ๊ตฌ์กฐ์ ์œผ๋กœ ๋™์ผํ•˜๋‹ค.

์™ผ์ชฝ์—์„œ ์ถœ๋ฐœํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ render๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ๊ฑฐ์ณ ์˜ค๋ฅธ์ชฝ์˜ JSX์š”์†Œ๋กœ ๋ฆฌํ„ด๋œ ์˜ˆ์ด๋‹ค.

๐Ÿšถ๐Ÿปโ€โ™€๏ธ side Effect

๋ถ€์ž‘์šฉ, ๋ถ€์ˆ˜ํšจ๊ณผ๋ผ๊ณ ๋„ ๋ถ€๋ฅด๋Š” side Effect๋Š” ์ผ์ƒ ์ƒํ™œ์˜ ๋งฅ๋ฝ์—์„œ๋Š” ๋ถ€์ •์ ์ธ ์˜๋ฏธ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์ง€๋งŒ, ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์ธก๋ฉด์—์„œ๋Š” ๋‹จ์ˆœํžˆ ๋ถ€์ •์ ์ธ ์˜๋ฏธ๋กœ๋งŒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค.

์ปดํ“จํ„ฐ ๊ณผํ•™์—์„œ ํ•จ์ˆ˜๊ฐ€ ๊ฒฐ๊ณผ๊ฐ’ ์ด์™ธ์— ๋‹ค๋ฅธ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝ์‹œํ‚ฌ ๋•Œ ๋ถ€์ž‘์šฉ์ด ์žˆ๋‹ค๊ณ  ๋งํ•œ๋‹ค. (wikipedia)

let count = 0

function greetWithSideEffect(name) { // Input
	count = count + 1 // Side Effect!

	return `${name}๋‹˜ ์•ˆ๋…•ํ•˜์„ธ์š”!` // Output
}

greetWithSideEffect()๋ผ๋Š” ํ•จ์ˆ˜๋Š” ์ด๋ฆ„์„ ๋ฐ›์•„ ์ธ์‚ฟ๋ง์„ ๋ฆฌํ„ดํ•˜๋Š” ํ•จ์ˆ˜๋‹ค.
์ด ํ•จ์ˆ˜๋Š” ๋‹จ์ˆœํžˆ input๊ณผ output๋งŒ ์กด์žฌํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ ์•„๋‹ˆ๋‹ค. ์‹คํ–‰ํ•˜๋Š” ์ค‘๊ฐ„์— ์„œ๋“œํŒŒํ‹ฐ์— ์žˆ๋Š” count๋ผ๋Š” ๋ณ€์ˆ˜๋ฅผ ์กฐ์ž‘ํ•œ๋‹ค. ์ด๋Š” ํ•จ์ˆ˜์˜ ๊ฒฐ๊ณผ๊ฐ’ ์ด์™ธ์˜ ๋‹ค๋ฅธ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝ์‹œํ‚ค๋Š” ํ–‰์œ„์ด๋ฏ€๋กœ side Effect๋ผ ํ•  ์ˆ˜ ์žˆ๋‹ค.
์ด๋Ÿฌํ•œ ์ผ์€ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์—์„œ๋„ ์ผ์–ด๋‚  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์—์„œ์˜ side Effect๋Š” ๋žœ๋”๋ง์ด ์•„๋‹ˆ๊ณ  ์™ธ๋ถ€ ์„ธ๊ณ„์— ์˜ํ–ฅ์„ ์ฃผ๋Š” ์–ด๋– ํ•œ ํ–‰์œ„์ด๋‹ค.
๋Œ€ํ‘œ์ ์œผ๋กœ Data Fetching, DOM ์ง์ ‘ ์ ‘๊ทผ(ex. Event Listener ๋“ฑ๋ก), ๊ตฌ๋…(ex. SetInterval)๊ณผ ๊ฐ™์€ ํ–‰์œ„๋“ค์ด ์žˆ๋‹ค. ์ด๋“ค ๋ชจ๋‘๊ฐ€ ์ปดํฌ๋„ŒํŠธ์—์„œ ๊ผญ ํ•„์š”ํ•œ ๋Œ€ํ‘œ์ ์ธ side Effect์ด๋‹ค.

๐Ÿšถ๐Ÿป useEffect

์•ž์—์„œ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์˜ ๋ฆฌํ„ด ๊ฐ’์€ UI ์š”์†Œ์ด๋ฉฐ state, props์˜ ๋ณ€ํ™”๊ฐ€ ์žˆ์„ ๋•Œ๋งˆ๋‹ค ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋œ๋‹ค๊ณ  ํ–ˆ๋‹ค. ์ด ๋ง์€ ๋งค ๋žœ๋”๋ง ์‹œ body์— ์žˆ๋Š” ๋กœ์ง์ด ์‹คํ–‰๋œ๋‹ค๋Š” ๋œป์ด๋‹ค(ํ•œ ๋ฒˆ๋งŒ ๋žœ๋”๋ง๋˜๋„ ๋˜๋Š” ๊ฒƒ๋„ ๊ณ„์†ํ•ด์„œ ๋žœ๋”๋ง ๋œ๋‹ค๋Š” ๋ง). ๋žœ๋”๋ง๊ณผ ๋ฌด๊ด€ํ•œ ๋กœ์ง์ด ๋žœ๋”๋ง ๊ณผ์ •์—์„œ ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋žœ๋”๋ง ์ž์ฒด์— ์˜ํ–ฅ์„ ์ฃผ์–ด ์„ฑ๋Šฅ๋ฉด์—์„œ ์•…์˜ํ–ฅ์„ ๋ผ์น  ์ˆ˜ ์žˆ๋‹ค.

function greetWithSideEffect({ name }) { // Input
  // Bad!
  document.title = `${name}๋‹˜ ์•ˆ๋…•ํ•˜์„ธ์š”!`; // Side Effect

  return <div>{`${name}๋‹˜ ์•ˆ๋…•ํ•˜์„ธ์š”!`}</div>; // Output
}

React์—์„œ๋Š” ์ด๋Ÿฐ side Effect๋ฅผ ์ผ์œผํ‚ค๊ธฐ ์ ์ ˆํ•œ ์žฅ์†Œ๋กœ useEffect hook์„ ์ œ๊ณตํ•œ๋‹ค.
๊ณต์‹๋ฌธ์„œ์—๋Š” "React์˜ ์ˆœ์ˆ˜ํ•œ ํ•จ์ˆ˜์ ์ธ ์„ธ๊ณ„์—์„œ ๋ช…๋ น์ ์ธ ์„ธ๊ณ„๋กœ์˜ ํƒˆ์ถœ๊ตฌ๋กœ ์ƒ๊ฐํ•˜์„ธ์š”"๋ผ๊ณ  ์„ค๋ช…ํ•˜๊ณ  ์žˆ๋Š”๋ฐ, ๋ฌด์Šจ ๋ง์ธ์ง€ ๋ชจ๋ฅด๊ฒ ๋‹ค.
์—ฌ๊ธฐ์„œ "์ˆœ์ˆ˜ํ•œ ์„ธ๊ณ„"๋Š” ๋žœ๋”๋ง(input -> output)์„ ๋œปํ•˜๊ณ , ๋žœ๋”๋ง ์ด์™ธ์— ์ผ์œผ์ผœ์•ผ ํ•˜๋Š” side Effect๋ฅผ ์ผ์œผํ‚ฌ ํƒˆ์ถœ๊ตฌ๋กœ useEffect๋ฅผ ์‚ฌ์šฉํ•˜๋ผ๋Š” ๋ง์ด๋‹ค.
useEffect๋Š” side Effect๋ฅผ ๋žœ๋”๋ง ์ดํ›„์— ๋ฐœ์ƒ์‹œํ‚จ๋‹ค(์˜ˆ์™ธ๊ฐ€ ์žˆ๋Š”๋ฐ useLayoutEffect ์ด๋‹ค).useEffect๊ฐ€ ์ˆ˜ํ–‰๋˜๋Š” ์‹œ์ ์— ์ด๋ฏธ DOM์ด ์—…๋ฐ์ดํŠธ ๋˜์—ˆ์Œ์„ ๋ณด์žฅํ•œ๋‹ค๋Š” ๋œป์ด๊ณ , ๋‹ฌ๋ฆฌ ๋งํ•˜๋ฉด side Effect๊ฐ€ ๋žœ๋”๋ง์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Œ์„ ๋œปํ•œ๋‹ค.

import { useEffect } from 'react';

function greetWithSideEffect({ name }) { // Input
  useEffect(() => {
    // Good!
    document.title = `${name}๋‹˜ ์•ˆ๋…•ํ•˜์„ธ์š”!`; // Side Effect
  }, [name]);

  return <div>{`${name}๋‹˜ ์•ˆ๋…•ํ•˜์„ธ์š”!`}</div>; // Output
}

๋งŒ์•ฝ side Effect ์ดํ›„ ์—…๋ฐ์ดํŠธ ๋œ ์ •๋ณด๊ฐ€ ์žˆ์–ด ์ƒˆ๋กญ๊ฒŒ ํ™”๋ฉด์ด ๊ทธ๋ ค์ ธ์•ผ ํ•  ๊ฒฝ์šฐ(state, props์˜ ์—…๋ฐ์ดํŠธ) ์ƒˆ๋กญ๊ฒŒ ๋žœ๋”๋ง์„ ์ผ์œผํ‚จ๋‹ค.
ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋Š” ๊ฐ€์žฅ ์ตœ์‹ ํ™”๋œ state์™€ props๋ฅผ ๋ฐ˜์˜ํ•ด ํ™”๋ฉด์— ๋ฟŒ๋ ค์ค€๋‹ค. Effect๋ฅผ ์ผ์œผํ‚ฌ ํƒ€์ด๋ฐ์€ useEffect์˜ ๋‘ ๋ฒˆ์งธ ์ธ์ž์ธ ์˜์กด์„ฑ ๋ฐฐ์—ด(Dependency Array)๋ฅผ ํ†ตํ•ด ํ‘œํ˜„ํ•œ๋‹ค.

๐Ÿšถ๐Ÿพโ€โ™€๏ธ Rendering Cycle with useEffect

useEffect์˜ ๋‹ค๋ฅธ ํ˜•ํƒœ ์‚ฌ์šฉ.
๋‘ ๋ฒˆ์งธ ์ธ์ž์— ๊ฐ์ง€ํ•  ๊ฐ’์„ ๋ฐฐ์—ด๋กœ ๋„˜๊ฒจ์ฃผ๋ฉด ํ•ด๋‹น ๊ฐ’๋“ค์ด ๋ณ€๊ฒฝ๋˜์—ˆ์„ ๋•Œ๋งŒ ์‹คํ–‰๋˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.

import { useEffect } from "react"

// ์‚ฌ์šฉ๋ฒ•
useEffect( ์‹คํ–‰์‹œํ‚ฌ ๋™์ž‘, [ ํƒ€์ด๋ฐ ] )
document.addEventListener("ํƒ€์ด๋ฐ", ์‹คํ–‰์‹œํ‚ฌ ๋™์ž‘) // ์ถ”์ƒํ™” ํ•œ ์˜ˆ์‹œ

// ๋งค ๋ Œ๋”๋ง๋งˆ๋‹ค Side Effect๊ฐ€ ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ
useEffect(() => {
  // Side Effect
})

// Side Effect๊ฐ€ ์ฒซ ๋ฒˆ์งธ ๋ Œ๋”๋ง ์ดํ›„ ํ•œ๋ฒˆ ์‹คํ–‰ ๋˜๊ณ ,
// ์ดํ›„ ํŠน์ • ๊ฐ’์˜ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ฐ์ง€ํ–ˆ์„ ๋•Œ๋งˆ๋‹ค ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ
useEffect(() => {
  // Side Effect
}, [value])

// Side Effect๊ฐ€ ์ฒซ ๋ฒˆ์งธ ๋ Œ๋”๋ง ์ดํ›„ ํ•œ๋ฒˆ ์‹คํ–‰ ๋˜๊ณ ,
// ์ดํ›„ ์–ด๋–ค ๊ฐ’์˜ ์—…๋ฐ์ดํŠธ๋„ ๊ฐ์ง€ํ•˜์ง€ ์•Š๋„๋ก ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ
useEffect(() => {
  // Side Effect
}, [])

์œ„ ์ฝ”๋“œ๋ฅผ ๊ทธ๋ฆผ์œผ๋กœ ๋‚˜ํƒ€๋‚ด๋ฉด,

::ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์˜ ๋žœ๋”๋ง ์ ˆ์ฐจ
1. ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋žœ๋”๋ง ๋˜๋ฉด, ์ตœ์ดˆ๋กœ ์ง„ํ–‰๋˜๋Š” ๋žœ๋”๋ง์€ ๋ธŒ๋ผ์šฐ์ €์— ์ฒ˜์Œ์œผ๋กœ ์ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ณด์—ฌ์กŒ๋‹ค๋Š” ์˜๋ฏธ๋กœ mount๋ผ๊ณ  ํ‘œํ˜„.
2. useEffect ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋กœ ๋„˜๊ฒจ์ค€ ํ•จ์ˆ˜(callback)๊ฐ€ ์‹คํ–‰๋œ๋‹ค(side Effect).
3. ๋‹ค์‹œ ๋žœ๋”๋ง์ด ์ผ์–ด๋‚œ๋‹ค(state๋‚˜ props๊ฐ€ ๋ณ€๊ฒฝ๋œ ๊ฒฝ์šฐ)
4. useEffect๋Š” ๋‘ ๋ฒˆ์งธ ์ธ์ž์— ๋“ค์–ด์žˆ๋Š” ์˜์กด์„ฑ ๋ฐฐ์—ด์„ ์ฒดํฌํ•œ๋‹ค.

  • 4-1. ๋งŒ์•ฝ ๋‘ ๋ฒˆ์งธ ์ธ์ž์— ์•„๋ฌด๋Ÿฐ ๊ฐ’๋„ ๋„˜๊ธฐ์ง€ ์•Š์•˜๊ฑฐ๋‚˜ / ์ธ์ž๋กœ ๋„˜๊ธด ๋ฐฐ์—ด์— ๋“ค์–ด์žˆ๋Š” ๊ฐ’ ์ค‘ ์—…๋ฐ์ดํŠธ๋œ ๊ฒƒ์ด ํ•˜๋‚˜๋ผ๋„ ์žˆ์œผ๋ฉด ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋กœ ๋„˜๊ฒจ์ค€ ํ•จ์ˆ˜(callback)๊ฐ€ ์‹คํ–‰๋œ๋‹ค(side Effect).
  • 4-2. ํ•˜๋‚˜๋„ ์—†๊ฑฐ๋‚˜ ๋นˆ ๋ฐฐ์—ด์ด๋ผ๋ฉด ์•„๋ฌด ์ผ๋„ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค.
  1. ๋งŒ์•ฝ ์•ž์—์„œ ์ผ์œผํ‚จ Effect์—์„œ state๋‚˜ props๋ฅผ ๋ณ€๊ฒฝ์‹œ์ผฐ๋‹ค๋ฉด ๋‹ค์‹œ ๋žœ๋”๋ง๋œ๋‹ค.
  2. ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ•„์š” ์—†์–ด์ง€๋ฉด ํ™”๋ฉด์—์„œ ์‚ฌ๋ผ์ง„๋‹ค. ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ธŒ๋ผ์šฐ์ €์˜ ํ™”๋ฉด์—์„œ ์‚ฌ๋ผ์กŒ๋‹ค๋Š” ์˜๋ฏธ๋กœ unmount๋ผ ํ‘œํ˜„ํ•œ๋‹ค.
profile
ไธๆ€•ๆ…ข, ๅชๆ€•็ซ™

0๊ฐœ์˜ ๋Œ“๊ธ€