useEffect ์๋ฒฝ ๊ฐ์ด๋
March 9, 2019 โข ๐ฑ๐ฑ๐ฑ๐ฑ 48 min read
Translated by readers into: Portuguรชs do Brasil โข ๆฅๆฌ่ช โข ็ฎไฝไธญๆ โข ็น้ซไธญๆ โข ํ๊ตญ์ด
Read the original โข Improve this translation โข View all translated posts
์ฌ๋ฌ๋ถ์ Hooks๋ก(์ดํ ํ ) ๋ช ๊ฐ์ ์ปดํฌ๋ํธ๋ฅผ ์์ฑํด ๋ดค์ ๊ฒ๋๋ค. ์๋ง ์์ ์ฑ์์๋ผ๊ณ ํด๋์. ์๋ง ๋์ฒด์ ์ผ๋ก ๋ง์กฑํ์ จ๊ฒ ์ฃ . API๊ฐ ํธ๋ฆฌํ๋ค๋ ๋๋์ ๋ฐ๊ณ ๋ฒ์จ ๋ช ๊ฐ์ง ํธ๋ฆญ์ ์ตํ๊ธฐ๋ ํ์ ๊ฒ๋๋ค. ์ฌ์ง์ด ์ปค์คํ ํ ์ ์์ฑํ์ฌ ๋ฐ๋ณต๋๋ ๋ก์ง์ ์ถ์ถํด๋ด๊ธฐ๋ ํ์ต๋๋ค(300์ค์ ์ฝ๋๊ฐ ์ค์ด๋ค์๋ค์!). ๊ทธ๋์ ๋๋ฃ๋ค์๊ฒ ๋ณด์ฌ์ฃผ๋ฉด ๋๋ฃ๋ค์ โ๋๋จํ๋ค์โ ๋ผ๊ณ ๋งํ๊ฒ ์ง์.
ํ์ง๋ง ๋๋๋ก useEffect
๋ฅผ ์ธ ๋๋ง๋ค ๋ญ๊ฐ ์ ๋ค์ด๋ง์ง ์์ต๋๋ค. ๋ญ๊ฐ ๋์น๊ณ ์๋ค๋ ๊ธฐ๋ถ์ ๋๋ผ๋ฉฐ ๊ดด๋ก์์ ๋๋ผ๊ธฐ๋ ํฉ๋๋ค. ์ฒ์์ ๋ณด๋ฉด ํด๋์ค ์ปดํฌ๋ํธ์ ๋ผ์ดํ์ฌ์ดํด ๋ฉ์๋์ ๋น์ทํ๋ค๊ณ ๋๋๋๋ค๋งโฆ ์ ๋ง ๊ทธ๋ด๊น์? ์ ์ ์๊ฐ์ด ์ง๋๋ฉด์ ์ค์ค๋ก์๊ฒ ์๋์ ๊ฐ์ ์ง๋ฌธ์ ํ๊ฒ ๋ฉ๋๋ค.
- ๐ค
useEffect
๋กcomponentDidMount
๋์์ ํ๋ด๋ด๋ ค๋ฉด ์ด๋ป๊ฒ ํ์ง? - ๐ค
useEffect
์์์ ๋ฐ์ดํฐ ํ์นญ(Data fetching)์ ์ด๋ป๊ฒ ํด์ผํ ๊น? ๋๋ฒ์งธ ์ธ์๋ก ์ค๋ ๋ฐฐ์ด([]
) ์ ๋ญ์ง? - ๐ค ์ดํํธ๋ฅผ ์ผ์ผํค๋ ์์กด์ฑ ๋ฐฐ์ด์ ํจ์๋ฅผ ๋ช ์ํด๋ ๋๋๊ฑธ๊น?
- ๐ค ์ ๊ฐ๋์ฉ ๋ฐ์ดํฐ ํ์นญ์ด ๋ฌดํ๋ฃจํ์ ๋น ์ง๋๊ฑธ๊น?
- ๐ค ์ ๊ฐ๋์ฉ ์ดํํธ ์์์ ์ด์ state๋ prop ๊ฐ์ ์ฐธ์กฐํ ๊น?
์ ๊ฐ ์ฒ์ ํ ์ ์ฌ์ฉํ ๋๋, ์์ ์ง๋ฌธ์ ๋๊ฐ์ด ํผ๋์ค๋ฌ์ด ๊ธฐ๋ถ์ ๋๊ผ์ต๋๋ค. ์ฌ์ง์ด ์ด๊ธฐ ๋ฌธ์๋ฅผ ์์ฑํ๋ฉด์๋ ๋๋ ๋ฏธ๋ฌํ ๋ถ๋ถ์ ๋ํด ์ ๋๋ก ํ์ ํ์ง ๋ชปํ๊ณ ์์์ต๋๋ค. ๋ช ๋ฒ์ โ์ํ ๋ชจ๋จผํธ(aha moment, ํน์ ์์ด๋์ด์ ๋ํด ์๊ฐ์ ์ป๊ฒ ๋๋ ์๊ฐ ๋ฑ)โ ๋ฅผ ๊ฒช๊ณ ๋์ ์ฌ๋ฌ๋ถ๋ค์๊ฒ ์๊ฒ๋ ์ ์ ๊ณต์ ํ๊ณ ์ถ์ต๋๋ค. ์ด ์๋ฒฝ ๊ฐ์ด๋๋ฅผ ํตํด ์์ ์ง๋ฌธ์ ๋ช ๋ฐฑํ๊ฒ ๋ตํด ๋๋ฆฌ๊ฒ ์ต๋๋ค.
๋ต์ ์ป๊ธฐ์ ์์ ํ ๋ฐ์ง ๋ค๋ก ๋ฌผ๋ฌ๋์ผ ํฉ๋๋ค. ์ด ๊ธ์ ๋ชฉ์ ์ ๋จ์ํ ์์ฝ๋ ์ ๋ณด๋ฅผ ๋ชฉ๋ก ํํ๋ก ์ ๊ณตํ๋๊ฒ ์๋๋๋ค. ์ง์ง ๋ชฉ์ ์ ์ฌ๋ฌ๋ถ์ด useEffect
๋ฅผ โ์์ ํโ ์ดํดํ๋๋ก ๋ง๋๋ ๊ฒ์
๋๋ค. ์ค์ ๋ก๋ ์์์ผ ํ ๊ฒ์ด ๊ทธ๋ฆฌ ๋ง์ง ์์ ๊ฒ์
๋๋ค. ์ค์ ๋ก ๋๋ถ๋ถ์ ์๊ฐ์ ์ด์ ์ ๋ฐฐ์ ๋ ๊ฒ์ ์์ด๋ฒ๋ฆฌ๋๋ฐ(unlearning) ํ ์ ํ ๊ฒ์
๋๋ค.
์ ๊ฐ useEffect
ํ
์ ํด๋์ค ์ปดํฌ๋ํธ์ ๋ผ์ดํ์ฌ์ดํด์ด๋ผ๋ ์ต์ํ ํ๋ฆฌ์ฆ์ ํตํด ๋ฐ๋ผ๋ณด๋ ๊ฒ์ ๊ทธ๋ง๋์ ๋ชจ๋ ๊ฒ์ด ๋ช
๋ฐฑํ๊ฒ ๋ค๊ฐ์์ต๋๋ค.
โ์๊ณ ์๋ ๊ฒ์ ์ ๋ถ ์์ด๋ฒ๋ฆฌ๊ฒโ - ์๋ค
์ด ๊ธ์ ๋
์ ์ฌ๋ฌ๋ถ์ด ์ด๋ ์ ๋ useEffect
API์ ์ต์ํ๋ค๋ ๊ฒ์ ์ ์ ๋ก ํฉ๋๋ค.
์ด ๊ธ์ ์์ฃผ ๊น๋๋ค. ํ๋์ ์์ ์ฑ ์์ค์ ๋๋ค. ์ ๊ฐ ๊ฐ์ธ์ ์ผ๋ก ์ ํธํ๋ ๋ฐฉ์์ผ๋ก ์์ฑํ์ต๋๋ค. ํ์ง๋ง ์๋๋ฌ ์ดํด๋ณด์๊ฑฐ๋ ๊ธด ๊ธ์ ์ ๊ฒฝ์ฐ๊ณ ์ถ์ง ์์ ๊ฒฝ์ฐ๋ฅผ ์ํด ๋ฐ๋ก ์๋์ ์์ฝ๋ณธ(TLDR)์ ๋ฌ์ ๋์์ต๋๋ค.
๊น์ด ํ๊ณ ๋๋ ๊ธ์ด ๋ถํธํ์ ๊ฒฝ์ฐ, ์๋์ ๋ด์ฉ์ ์ข ๋ ์์๋ฃ๊ธฐ ์ฝ๊ฒ ์ค๋ช ํ๋ ๋ค๋ฅธ ๊ธ์ด๋ ๊ฐ์ข๊ฐ ๋์ค๊ธธ ๊ธฐ๋ค๋ฆฌ์ ์ผ ํ ์๋ ์์ต๋๋ค. ๋ฆฌ์กํธ๊ฐ 2013๋ ์ ์ฒ์ ๋์จ ๋ค ๊ฐ๋ฐ์๋ค์ด ๊ธฐ์กด๊ณผ ๋ค๋ฅธ ๋ฉํ ๋ชจ๋ธ์ ์ตํ๊ณ ๋ค๋ฅธ ์ฌ๋์๊ฒ ๊ฐ๋ฅด์น๊ธฐ ์์ํ๊ธฐ๊น์ง ์๊ฐ์ด ์ข ๊ฑธ๋ ธ๋ฏ ๋ง์ ๋๋ค.
TLDR (Too Long; Didnโt Read - ์์ฝ)
๊ธ ์ ์ฒด๋ฅผ ์ฝ๊ณ ์ถ์ง ์์ ๋ถ๋ค์ ์ํด ์ฌ๊ธฐ ์์ฝ๋ณธ์ ๋ง๋ จํด ๋์์ต๋๋ค. ์ฝ๋ค๊ฐ ์ด๋ค ๋ถ๋ถ์ด ์ ์ดํด๊ฐ ๋์ง ์์ผ์ จ๋ค๋ฉด ์ฐ๊ด๋ ๋ถ๋ถ์ด ๋์ฌ ๋๊น์ง ์คํฌ๋กค์ ์๋๋ก ๋ด๋ ค๋ณด์ธ์.
๋ง์ฝ ๊ธ ์ ์ฒด๋ฅผ ์ฝ์ผ์ค ๊ฑฐ๋ผ๋ฉด ํธํ๊ฒ ์คํตํ์ ๋ ๋ฉ๋๋ค. ์ด ๋ถ๋ถ์ผ๋ก ์ด๋ํ๋ ๋งํฌ๋ฅผ ๊ธ ๋์ ๋ฌ์ ๋๊ฒ ์ต๋๋ค.
๐ค ์ง๋ฌธ: useEffect
๋ก componentDidMount
๋์์ ํ๋ด๋ด๋ ค๋ฉด ์ด๋ป๊ฒ ํ์ง?
์์ ํ ๊ฐ์ง ์์ง๋ง useEffect(fn, [])
์ผ๋ก ๊ฐ๋ฅํฉ๋๋ค. componentDidMount
์ ๋ฌ๋ฆฌ prop๊ณผ state๋ฅผ ์ก์๋ ๊ฒ์
๋๋ค. ๊ทธ๋์ ์ฝ๋ฐฑ ์์์๋ ์ด๊ธฐ prop๊ณผ state๋ฅผ ํ์ธํ ์ ์์ต๋๋ค. ๋ง์ฝ โ์ต์ ์โ ์ํ ๋ฑ์ ์ํ๋ค๋ฉด, ref์๋ค ๋ด์๋ ์๋ ์์ต๋๋ค. ํ์ง๋ง ๋ณดํต ๋ ๊ฐ๋จํ๊ฒ ์ฝ๋๋ฅผ ๊ตฌ์กฐํํ๋ ๋ฐฉ๋ฒ์ด ์๊ธฐ ๋๋ฌธ์ ๊ตณ์ด ์ด ๋ฐฉ๋ฒ์ ์ธ ํ์๋ ์์ต๋๋ค. ์ดํํธ๋ฅผ ๋ค๋ฃจ๋ ๋ฉํ ๋ชจ๋ธ์ componentDidMount
๋ ๋ค๋ฅธ ๋ผ์ดํ์ฌ์ดํด ๋ฉ์๋์ ๋ค๋ฅด๋ค๋ ์ ์ ์ธ์งํ์
์ผ ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๋ค ๋ผ์ดํ์ฌ์ดํด ๋ฉ์๋์ ๋น์ทํ ๋์์ ํ๋๋ก ๋ง๋๋ ๋ฐฉ๋ฒ์ ์ฐพ์ผ๋ ค๊ณ ํ๋ฉด ์คํ๋ ค ํผ๋์ ๋ ํค์ธ ๋ฟ์
๋๋ค. ๋ ์์ฐ์ ์ผ๋ก ์ ๊ทผํ๊ธฐ ์ํด โ์ดํํธ ๊ธฐ์ค์ผ๋ก ์๊ฐํด์ผ(thinking in effects)โ ํ๋ฉฐ ์ด ๋ฉํ ๋ชจ๋ธ์ ๋๊ธฐํ๋ฅผ ๊ตฌํํ๋ ๊ฒ์ ๊ฐ๊น์ง ๋ผ์ดํ์ฌ์ดํด ์ด๋ฒคํธ์ ์๋ตํ๋ ๊ฒ๊ณผ๋ ๋ค๋ฆ
๋๋ค.
๐ค ์ง๋ฌธ: useEffect
์์์ ๋ฐ์ดํฐ ํ์นญ์ ์ด๋ป๊ฒ ํด์ผํ ๊น? ๋๋ฒ์งธ ์ธ์๋ก ์ค๋ ๋ฐฐ์ด([]
) ์ ๋ญ์ง?
์ด ๋งํฌ์ ๊ธ์ด useEffect
๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๋ ๋ฐฉ๋ฒ์ ํ์
ํ๋๋ฐ ์ข์ ๊ธฐ๋ณธ์๊ฐ ๋ฉ๋๋ค. ๊ธ์ ๊ผญ ๋๊น์ง ์ฝ์ด๋ณด์ธ์! ์ง๊ธ ์ฝ๊ณ ๊ณ์๋ ๊ธ์ฒ๋ผ ๊ธธ์ง ์์ต๋๋ค. []
๋ ์ดํํธ์ ๋ฆฌ์กํธ ๋ฐ์ดํฐ ํ๋ฆ์ ๊ด์ฌํ๋ ์ด๋ ํ ๊ฐ๋ ์ฌ์ฉํ์ง ์๊ฒ ๋ค๋ ๋ป์
๋๋ค. ๊ทธ๋์ ํ ๋ฒ ์ ์ฉ๋์ด๋ ์์ ํ๋ค๋ ๋ป์ด๊ธฐ๋ ํฉ๋๋ค. ์ด ๋น ๋ฐฐ์ด์ ์ค์ ๋ก ๊ฐ์ด ์ฌ์ฉ๋์ด์ผ ํ ๋ ๋ฒ๊ทธ๋ฅผ ์ผ์ผํค๋ ์ฃผ๋ ์์ธ ์ค ํ๋์
๋๋ค. ์๋ชป๋ ๋ฐฉ์์ผ๋ก ์์กด์ฑ ์ฒดํฌ๋ฅผ ์๋ตํ๋ ๊ฒ ๋ณด๋ค ์์กด์ฑ์ ํ์๋ก ํ๋ ์ํฉ์ ์ ๊ฑฐํ๋ ๋ช ๊ฐ์ง ์ ๋ต์(์ฃผ๋ก useReducer
, useCallback
) ์ตํ์ผ ํ ํ์๊ฐ ์์ต๋๋ค.
๐ค ์ง๋ฌธ: ์ดํํธ๋ฅผ ์ผ์ผํค๋ ์์กด์ฑ ๋ฐฐ์ด์ ํจ์๋ฅผ ๋ช ์ํด๋ ๋๋๊ฑธ๊น?
์ถ์ฒํ๋ ๋ฐฉ๋ฒ์ prop์ด๋ state๋ฅผ ๋ฐ๋์ ์๊ตฌํ์ง ์๋ ํจ์๋ ์ปดํฌ๋ํธ ๋ฐ๊นฅ์ ์ ์ธํด์ ํธ์ด์คํ
ํ๊ณ , ์ดํํธ ์์์๋ง ์ฌ์ฉ๋๋ ํจ์๋ ์ดํํธ ํจ์ ๋ด๋ถ์ ์ ์ธํ๋ ๊ฒ๋๋ค. ๊ทธ๋ฌ๊ณ ๋์ ๋ง์ฝ์ ๋๋ ๋ฒ์ ์์ ์๋ ํจ์๋ฅผ ์ดํํธ๊ฐ ์ฌ์ฉํ๊ณ ์๋ค๋ฉด (prop์ผ๋ก ๋ด๋ ค์ค๋ ํจ์ ํฌํจํด์), ๊ตฌํ๋ถ๋ฅผ useCallback
์ผ๋ก ๊ฐ์ธ์ธ์. ์ ์ด๋ฐ๊ฑธ ์ ๊ฒฝ์จ์ผ ํ ๊น์? ํจ์๋ prop๊ณผ state๋ก๋ถํฐ ๊ฐ์ โ๋ณผ ์โ ์์ต๋๋ค. ๊ทธ๋ฌ๋ฏ๋ก ๋ฆฌ์กํธ์ ๋ฐ์ดํฐ ํ๋ก์ฐ์ ์ฐ๊ด์ด ์์ง์. ์์ธํ ๋ต๋ณ์ ํ
FAQ ๋ถ๋ถ์ ์์ต๋๋ค.
๐ค ์ง๋ฌธ: ์ ๊ฐ๋์ฉ ๋ฐ์ดํฐ ํ์นญ์ด ๋ฌดํ๋ฃจํ์ ๋น ์ง๋๊ฑธ๊น?
์ดํํธ ์์์ ๋ฐ์ดํฐ ํ์นญ์ ํ ๋ ๋ ๋ฒ์งธ ์ธ์๋ก ์์กด์ฑ ๋ฐฐ์ด์ ์ ๋ฌํ์ง ์์์ ๋ ์๊ธธ ์ ์๋ ๋ฌธ์ ์
๋๋ค. ์ด๊ฒ ์์ผ๋ฉด ์ดํํธ๋ ๋งค ๋๋๋ง๋ค ์คํ๋ฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ state๋ฅผ ์ค์ ํ๋ ์ผ์ ๋ ๋ค์ ์ดํํธ๋ฅผ ์คํํ์ฃ . ์์กด์ฑ ๋ฐฐ์ด์ ํญ์ ๋ฐ๋๋ ๊ฐ์ ์ง์ ํด ๋๋ ๊ฒฝ์ฐ์๋ ๋ฌดํ ๋ฃจํ๊ฐ ์๊ธธ ์ ์์ต๋๋ค. ํ๋์ฉ ์ง์๋ณด๋ฉด์ ์ด๋ ๊ฐ์ด ๋ฌธ์ ์ธ์ง ํ์ธํ ์๋ ์์ง๋ง, ์ฌ์ฉํ๊ณ ์๋ ์์กด ๊ฐ์ ์ง์ฐ๋ ์ผ์(์๋๋ฉด ๋งน๋ชฉ์ ์ผ๋ก []
์ ์ง์ ํ๋ ๊ฒ์) ๋ณดํต ์๋ชป๋ ํด๊ฒฐ๋ฒ์
๋๋ค. ๊ทธ ๋์ ๋ฌธ์ ์ ๊ทผ์์ ํ์
ํ์ฌ ํด๊ฒฐํด์ผ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด ํจ์๊ฐ ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์ ์์ต๋๋ค. ๊ทธ๋ ๋ค๋ฉด ์ดํํธ ํจ์ ์์ ์ง์ด๋ฃ๊ฑฐ๋, ํจ์๋ฅผ ๊บผ๋ด์ ํธ์ด์คํ
ํ๊ฑฐ๋, useCallback
์ผ๋ก ๊ฐ์ธ์ ํด๊ฒฐํ ์ ์์ต๋๋ค. ๊ฐ์ฒด๊ฐ ์ฌ์์ฑ๋๋ ๊ฒ์ ๋ง์ผ๋ ค๋ฉด useMemo
๋ฅผ ๋น์ทํ ์ฉ๋๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
๐ค ์ง๋ฌธ: ์ ๊ฐ๋์ฉ ์ดํํธ ์์์ ์ด์ state๋ prop ๊ฐ์ ์ฐธ์กฐํ ๊น?
์ดํํธ๋ ์ธ์ ๋ ์์ ์ด ์ ์๋ ๋ธ๋ก ์์์ ๋๋๋ง์ด ์ผ์ด๋ ๋๋ง๋ค prop๊ณผ state๋ฅผ โ์ง์ผ๋ด ๋๋คโ. ์ด๋ ๊ฒ ํ๋ฉด ๋ฒ๊ทธ๋ฅผ ๋ฐฉ์งํ ์ ์์ง๋ง ์ด๋ค ๊ฒฝ์ฐ์๋ ์ง์ฆ๋ ์ ์์ต๋๋ค. ๊ทธ๋ด ๋๋ ๋ช ์์ ์ผ๋ก ์ด๋ค ๊ฐ์ ๊ฐ๋ณ์ฑ ref์ ๋ฃ์ด์ ๊ด๋ฆฌํ ์ ์์ต๋๋ค(๋งํฌ์ ์๋ ๊ธ ๋ง๋ฏธ์ ์ค๋ช ๋์ด ์์ต๋๋ค). ํน์ ๊ธฐ๋ํ ๊ฒ๊ณผ ๋ฌ๋ฆฌ ์ด์ ์ ๋๋๋ง๋ ๋์ prop์ด๋ state๊ฐ ๋ณด์ธ๋ค๋ฉด, ์๋ง๋ ์์กด์ฑ ๋ฐฐ์ด์ ๊ฐ์ ์ง์ ํ๋ ๊ฒ์ ๊น๋นกํ์ ๊ฒ๋๋ค. ์ด ๋ฆฐํธ ๊ท์น์ ์ฌ์ฉํ์ฌ ๊ทธ ๊ฐ์ ํ์ ํ ์ ์๋๋ก ์ฐ์ตํด ๋ณด์ธ์. ๋ฉฐ์น ์์ผ๋ก ์์ฐ์ค๋ ๋ชธ์ ๋ฐธ ๊ฒ์ ๋๋ค. ๋ํ FAQ ๋ฌธ์์์ ์ด ๋ต๋ณ ๋ถ๋ถ์ ์ฝ์ด๋ณด์ธ์.
์ ์์ ๋ณธ์ด ๋์์ด ๋์์ผ๋ฉด ์ข๊ฒ ๋ค์! ๊ทธ๋ผ ๋ณธ๋ก ์ผ๋ก ๋ค์ด๊ฐ ๋ณด๊ฒ ์ต๋๋ค.
๋ชจ๋ ๋๋๋ง์ ๊ณ ์ ์ Prop๊ณผ State๊ฐ ์๋ค
์ดํํธ์ ๋ํด ์ด์ผ๊ธฐํ๊ธฐ ์ ์, ๋จผ์ ๋๋๋ง์ ๋ํด ์ด์ผ๊ธฐํด์ผ ํฉ๋๋ค.
์ฌ๊ธฐ ์นด์ดํฐ ์ปดํฌ๋ํธ๊ฐ ์์ต๋๋ค. ํ์ด๋ผ์ดํธ๋ ์ค์ ์์ธํ ๋ด ์ฃผ์ธ์.
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
์ด๊ฒ ๋ฌด์จ ๋ป์ผ๊น์? count
๊ฐ ์ด์ฐ์ ์ฐ state์ ๋ณํ๋ฅผ ๊ด์ฐฐํ์ฌ ์๋์ผ๋ก ์
๋ฐ์ดํธ ํ๋ค๋ ๊ฑธ๊น์? ์ฒ์์ ๋ฆฌ์กํธ๋ฅผ ๋ฐฐ์ฐ๋ฉด์ ์ง๊ด์ ์ผ๋ก ๋ฐ์๋ค์ผ ๋๋ ์ ์ฉํ ์๊ฐ์ผ ์ ์์ง๋ง ์ ํํ ๋ฉํ ๋ชจ๋ธ์ ์๋๋๋ค.
์ด ์์ ์์ count
๋ ๊ทธ์ ์ซ์์
๋๋ค. ๋ง๋ฒ์ โ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉโ ์ด๋ โ์์ณโ ๋ โํ๋ก์โ, ํน์ ๋น์ทํ ๊ทธ ์ด๋ค ๊ฒ๋ ์๋๋๋ค. ๊ทธ๋ฅ ์๋์ ๊ฐ์ด ๋จ์ํ ์ซ์์ ๋ถ๊ณผํฉ๋๋ค.
const count = 42;
// ...
<p>You clicked {count} times</p>
// ...
์ฒ์์ผ๋ก ์ปดํฌ๋ํธ๊ฐ ๋๋๋ง๋ ๋, useState
๋ก๋ถํฐ ๊ฐ์ ธ์จ count
๋ณ์๋ 0
์
๋๋ค. setCount(1)
์ ํธ์ถํ๋ฉด, ๋ค์ ์ปดํฌ๋ํธ๋ฅผ ํธ์ถํ๊ณ . ์ด ๋ count
๋ 1
์ด ๋๋ ์์
๋๋ค.
// ์ฒ์ ๋๋๋ง ์
function Counter() {
const count = 0; // useState() ๋ก๋ถํฐ ๋ฆฌํด // ...
<p>You clicked {count} times</p>
// ...
}
// ํด๋ฆญํ๋ฉด ํจ์๊ฐ ๋ค์ ํธ์ถ๋๋ค
function Counter() {
const count = 1; // useState() ๋ก๋ถํฐ ๋ฆฌํด // ...
<p>You clicked {count} times</p>
// ...
}
// ๋ ํ๋ฒ ํด๋ฆญํ๋ฉด, ๋ค์ ํจ์๊ฐ ํธ์ถ๋๋ค
function Counter() {
const count = 2; // useState() ๋ก๋ถํฐ ๋ฆฌํด // ...
<p>You clicked {count} times</p>
// ...
}
state๋ฅผ ์
๋ฐ์ดํธํ ๋๋ง๋ค, ๋ฆฌ์กํธ๋ ์ปดํฌ๋ํธ๋ฅผ ํธ์ถํฉ๋๋ค. ๋งค ๋๋ ๊ฒฐ๊ณผ๋ฌผ์ ๊ณ ์ ์ counter
์ํ ๊ฐ์ โ์ดํด๋ด
๋๋คโ. ๊ทธ๋ฆฌ๊ณ ์ด ๊ฐ์ ํจ์ ์์ ์์๋ก ์กด์ฌํ๋ ๊ฐ์
๋๋ค.
๋ฐ๋ผ์ ์์ ํ์ํ ์ค์ ์ด๋ ํ ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ๋ ์ํํ์ง ์์ต๋๋ค.
<p>You clicked {count} times</p>
์ด๊ฑด ๋๋๋ง ๊ฒฐ๊ณผ๋ฌผ์ ์ซ์ ๊ฐ์ ๋ด์ฅํ๋ ๊ฒ์ ๋ถ๊ณผํฉ๋๋ค. ์ด ์ซ์ ๊ฐ์ ๋ฆฌ์กํธ๋ฅผ ํตํค ์ ๊ณต๋ฉ๋๋ค. setCount
๋ฅผ ํธ์ถํ ๋, ๋ฆฌ์กํธ๋ ๋ค๋ฅธ count
๊ฐ๊ณผ ํจ๊ป ์ปดํฌ๋ํธ๋ฅผ ๋ค์ ํธ์ถํฉ๋๋ค. ๊ทธ๋ฌ๋ฉด ๋ฆฌ์กํธ๋ ๊ฐ์ฅ ์ต์ ์ ๋๋๋ง ๊ฒฐ๊ณผ๋ฌผ๊ณผ ์ผ์นํ๋๋ก DOM์ ์
๋ฐ์ดํธ ํฉ๋๋ค.
๋ช
์ฌํ์
์ผ ํ ์ ์ ์ฌ๋ ํน์ ๋๋๋ง ์ ๊ทธ ์์ ์๋ count
์์๋ ์๊ฐ์ด ์ง๋๋ค๊ณ ๋ฐ๋๋ ๊ฒ์ด ์๋๋ผ๋ ๊ฒ์
๋๋ค. ์ปดํฌ๋ํธ๊ฐ ๋ค์ ํธ์ถ๋๊ณ , ๊ฐ๊ฐ์ ๋๋๋ง๋ง๋ค ๊ฒฉ๋ฆฌ๋ ๊ณ ์ ์ count
๊ฐ์ โ๋ณด๋โ ๊ฒ์
๋๋ค.
(์ด ๊ณผ์ ์ ์์ธํ ์๊ณ ์ถ๋ค๋ฉด, ์ ๊ฐ ์ด ๋ค๋ฅธ ๊ธ UI ๋ฐํ์์ผ๋ก์์ React๋ฅผ ์ฝ์ด๋ณด์ธ์.)
๋ชจ๋ ๋๋๋ง์ ๊ณ ์ ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๊ฐ์ง๋ค
์ฌ๊ธฐ๊น์ง ํ ๋งํ๋ค์. ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ๊ฒฝ์ฐ๋ ์ด๋จ๊น์?
์๋์ ์์ ๋ฅผ ๋ด ์ฃผ์ธ์. ์ด ์ปดํฌ๋ํธ๋ 3์ด ๋ค์ count
๊ฐ๊ณผ ํจ๊ป ์ผ๋ฟ(alert)์ ๋์์ค๋๋ค.
function Counter() {
const [count, setCount] = useState(0);
function handleAlertClick() { setTimeout(() => { alert('You clicked on: ' + count); }, 3000); } return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
<button onClick={handleAlertClick}>
Show alert </button> </div> );
}
์ ๊ฐ ๋จ๊ณ๋ณ๋ก ์ด๋ฐ ๊ณผ์ ์ ์คํํด๋ณธ๋ค๊ณ ํ์ฃ .
- ์นด์ดํฐ๋ฅผ 3์ผ๋ก ์ฆ๊ฐ์ํจ๋ค
- โShow alertโ ์ ๋๋ฅธ๋ค
- ํ์์์์ด ์คํ๋๊ธฐ ์ ์ ์นด์ดํฐ๋ฅผ 5๋ก ์ฆ๊ฐ์ํจ๋ค
์ด๋ด ๋ ์ผ๋ฟ์๋ ์ด๋ค ๊ฐ์ด ๋ํ๋ ๊น์? ์ผ๋ฟ์ด ๋ฑ์ฅํ ๋์ ๊ฐ์ธ 5๊ฐ ๋์ฌ๊น์? ์๋๋ฉด ์ ๊ฐ โShow alertโ ๋ฒํผ์ ํด๋ฆญํ ๋น์์ ๊ฐ์ธ 3์ด ๋์ฌ๊น์?
์คํฌ ๋ฐฉ์ง
ํ๋ฒ ์ง์ ํด ๋ณด์ธ์!
๋ง์ฝ์ ์คํํด ๋ณธ ๊ฒฐ๊ณผ๊ฐ ์ ๋ฉ๋์ด ๋์ง ์๋๋ค๋ฉด, ์กฐ๊ธ ๋ ์ค์ง์ ์ธ ์๋ฅผ ์์ํด ๋ณด์ธ์. ์ฑํ ์ฑ์์ state์ ํ์ฌ ์์ ์ ID๋ฅผ ๊ฐ์ง๊ณ ์๋ ์ํ์์ ์ ์ก ๋ฒํผ์ ๋๋ฅธ ๊ฒ์ด๋ ๋ง์ฐฌ๊ฐ์ง์ ๋๋ค. ์ ๊ฒฐ๊ณผ๊ฐ์ผ๋ก 3์ด ๋์๋์ง ์ด ๊ธ์ด ์์ธํ ์ค๋ช ํด ์ค๋๋ค.
์ผ๋ฟ์ ๋ฒํผ์ ํด๋ฆญํ ๋์ state๋ฅผ ์ก์๋ ๊ฒ์ ๋๋ค.
(๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ๋์ํ ์ ์๋๋ก ๊ตฌํํ๋ ๋ฐฉ๋ฒ๋ ์์ต๋๋ค๋ง ์ง๊ธ์ ์ผ๋ฐ์ ์ธ ๊ฒฝ์ฐ๋ฅผ ์ง์คํด์ ๋ค๋ฃจ๊ฒ ์ต๋๋ค. ๋ฉํ ๋ชจ๋ธ์ ํ์ฑํ ๋ ์ค์ํ ๊ฒ์ โ๊ฐ์ฅ ์ฌ์ด ๋ฐฉ๋ฒโ๊ณผ ๊ธด๊ธ ํผ๋ ํด์น๋ฅผ ๊ตฌ๋ถํ๋ ๊ฒ์ ๋๋ค.)
๊ทธ๋ฐ๋ฐ ์ ์ด๋ ๊ฒ ๋์ํ ๊น์?
์์ ์ฐ๋ฆฌ๋ count
๊ฐ์ด ๋งค๋ฒ ๋ณ๊ฐ์ ํจ์ ํธ์ถ๋ง๋ค ์กด์ฌํ๋ ์์๊ฐ์ด๋ผ๋ ์ด์ผ๊ธฐ๋ฅผ ํ์ต๋๋ค. ์ด๊ฑธ ํนํ ๊ฐ์กฐํ๊ณ ์ถ์๋ฐ, ์ฐ๋ฆฌ์ ํจ์๋ ์ฌ๋ฌ๋ฒ ํธ์ถ๋์ง๋ง(๋๋๋ง๋ง๋ค ํ ๋ฒ์ฉ), ๊ฐ๊ฐ์ ๋๋๋ง์์ ํจ์ ์์ count
๊ฐ์ ์์์ด์ ๋
๋ฆฝ์ ์ธ ๊ฐ(ํน์ ๋๋๋ง ์์ ์ํ)์ผ๋ก ์กด์ฌํฉ๋๋ค.
๋ฆฌ์กํธ๋ง ํน๋ณ์ด ์ด๋ ๊ฒ ๋์ํ๋๊ฒ ์๋๋๋ค. ๋ณดํต์ ํจ์๋ ๊ฐ์ ๋ฐฉ์์ผ๋ก ๋์ํฉ๋๋ค.
function sayHi(person) {
const name = person.name; setTimeout(() => {
alert('Hello, ' + name);
}, 3000);
}
let someone = {name: 'Dan'};
sayHi(someone);
someone = {name: 'Yuzhi'};
sayHi(someone);
someone = {name: 'Dominic'};
sayHi(someone);
์ด ์์ ์์, ์ธ๋ถ์ someone
๋ณ์๋ ์ฌ๋ฌ ๋ฒ ์ฌํ ๋น๋ฉ๋๋ค. (๋ฆฌ์กํธ ์ด๋๊ฐ์์ ํ์ฌ์ ์ปดํฌ๋ํธ ์ํ๊ฐ ๋ฐ๋ ์ ์๋ ๊ฒ์ฒ๋ผ์.) ํ์ง๋ง sayHi
๋ด๋ถ์์, ํน์ ํธ์ถ๋ง๋ค person
๊ณผ ์ฎ์ฌ์๋ name
์ด๋ผ๋ ์ง์ญ ์์๊ฐ ์กด์ฌํฉ๋๋ค. ์ด ์์๋ ์ง์ญ ์์์ด๊ธฐ ๋๋ฌธ์, ๊ฐ๊ฐ์ ํจ์ ํธ์ถ๋ก๋ถํฐ ๋ถ๋ฆฌ๋์ด ์์ต๋๋ค! ๊ฒฐ๊ณผ์ ์ผ๋ก ํ์์์ ์ด๋ฒคํธ๊ฐ ์คํ๋ ๋๋ง๋ค ๊ฐ์์ ์ผ๋ฟ์ ๊ณ ์ ์ name
์ ๊ธฐ์ตํ๊ฒ ๋ฉ๋๋ค.
์ด ์ค๋ช
์ ํตํด ํด๋ฆญ ์ ์ฐ๋ฆฌ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ count
๊ฐ์ ์ก์๋์๋์ง ์ ์ ์๊ฒ ๋์์ต๋๋ค. ๋ ํ๋ฒ ์๋์ ๊ฐ์ด ์นํํด๋ณด๋ฉด, ๋งค ๋๋๋ง ๋ง๋ค ๊ฐ๊ฐ์ count
๊ฐ์ โ๋ณด๋โ ๊ฒ์
๋๋ค.
// ์ฒ์ ๋๋๋ง ์
function Counter() {
const count = 0; // useState() ๋ก๋ถํฐ ๋ฆฌํด // ...
function handleAlertClick() {
setTimeout(() => {
alert('You clicked on: ' + count);
}, 3000);
}
// ...
}
// ํด๋ฆญํ๋ฉด ํจ์๊ฐ ๋ค์ ํธ์ถ๋๋ค
function Counter() {
const count = 1; // useState() ๋ก๋ถํฐ ๋ฆฌํด // ...
function handleAlertClick() {
setTimeout(() => {
alert('You clicked on: ' + count);
}, 3000);
}
// ...
}
// ๋ ํ๋ฒ ํด๋ฆญํ๋ฉด, ๋ค์ ํจ์๊ฐ ํธ์ถ๋๋ค
function Counter() {
const count = 2; // useState() ๋ก๋ถํฐ ๋ฆฌํด // ...
function handleAlertClick() {
setTimeout(() => {
alert('You clicked on: ' + count);
}, 3000);
}
// ...
}
๋ฐ๋ผ์ ํจ๊ณผ์ ์ผ๋ก, ๊ฐ๊ฐ์ ๋๋๋ง์ ๊ณ ์ ํ โ๋ฒ์ โ์ handleAlertClick
์ ๋ฆฌํดํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ฐ๊ฐ์ ๋ฒ์ ์ ๊ณ ์ ์ count
๋ฅผ โ๊ธฐ์ตํฉ๋๋คโ.
// ์ฒ์ ๋๋๋ง ์
function Counter() {
// ...
function handleAlertClick() {
setTimeout(() => {
alert('You clicked on: ' + 0); }, 3000);
}
// ...
<button onClick={handleAlertClick} /> // 0์ด ์์ ๋ค์ด์์ // ...
}
// ํด๋ฆญํ๋ฉด ํจ์๊ฐ ๋ค์ ํธ์ถ๋๋ค
function Counter() {
// ...
function handleAlertClick() {
setTimeout(() => {
alert('You clicked on: ' + 1); }, 3000);
}
// ...
<button onClick={handleAlertClick} /> // 1์ด ์์ ๋ค์ด์์ // ...
}
// ๋ ํ๋ฒ ํด๋ฆญํ๋ฉด, ๋ค์ ํจ์๊ฐ ํธ์ถ๋๋ค
function Counter() {
// ...
function handleAlertClick() {
setTimeout(() => {
alert('You clicked on: ' + 2); }, 3000);
}
// ...
<button onClick={handleAlertClick} /> // 2๊ฐ ์์ ๋ค์ด์์ // ...
}
๊ทธ๋์ ์ด ๋ฐ๋ชจ์์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ํน์ ๋๋๋ง์ โ์ํด ์์ผ๋ฉฐโ, ์ผ๋ฟ ํ์ ๋ฒํผ์ ํด๋ฆญํ ๋ ๊ทธ ๋๋๋ง ์์ ์ counter
state๋ฅผ ์ ์งํ ์ฑ๋ก ์ฌ์ฉํ๋ ๊ฒ์
๋๋ค.
ํน์ ๋๋๋ง ์ ๊ทธ ๋ด๋ถ์์ props์ state๋ ์์ํ ๊ฐ์ ์ํ๋ก ์ ์ง๋ฉ๋๋ค. props์ state๊ฐ ๋๋๋ง์ผ๋ก๋ถํฐ ๋ถ๋ฆฌ๋์ด ์๋ค๋ฉด, ์ด๋ฅผ ์ฌ์ฉํ๋ ์ด๋ ํ ๊ฐ(์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ํฌํจํ์ฌ)๋ ๋ถ๋ฆฌ๋์ด ์๋ ๊ฒ์
๋๋ค. ์ด๋ค๋ ๋ง์ฐฌ๊ฐ์ง๋ก ํน์ ๋๋๋ง์ โ์ํด ์์ต๋๋คโ. ๋ฐ๋ผ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด๋ถ์ ๋น๋๊ธฐ ํจ์๋ผ ํ ์ง๋ผ๋ ๊ฐ์ count
๊ฐ์ โ๋ณด๊ฒโ ๋ ๊ฒ์
๋๋ค.
์ฐธ๊ณ ๋
ธํธ: ์ ๋ ์์ ์์ ์์ handleAlertClick
ํจ์ ์์ ์ง์ ๊ตฌ์ฒด์ ์ธ count
๊ฐ์ ๋ฃ์ด์ ํ์ํ์ต๋๋ค. ์ด๋ฐ ๋ฐฉ์์ผ๋ก ์นํํ์ฌ ๋ณด๋ ๊ฒ์ ์์ ํ๋ฐ, count
๋ ๊ฐ๊ฐ์ ๋๋๋ง ๋ด๋ถ์์ ๋ณํ ์ ์๋ ๊ฐ์ด๊ธฐ ๋๋ฌธ์
๋๋ค. const
๋ก ์ ์ธ๋์ด์๋ ์ซ์ ๊ฐ์ด๊ธฐ ๋๋ฌธ์ด์ฃ . ๊ฐ์ฒด์ ๊ฐ์ด ๋ค๋ฅธ ๊ฐ์ ๋ํด์๋ ๊ฐ์ ์๊ฐ์ ํ ์ ์์ต๋๋ค๋ง, ์ค๋ก์ง ๋ถ๋ณ ๊ฐ์ ์ฌ์ฉํ๋ค๋ ์ ์ ๊ฐ ์์ด์ผ ํฉ๋๋ค. setSomething(newObj)
๋ฅผ ํธ์ถํ ๋ ๊ฐ์ฒด๋ฅผ ๋ณํํ์ง ์๊ณ ์ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ๋ ๊ฒ์ ๊ด์ฐฎ์ต๋๋ค. ์ด์ ๋๋๋ง์ ์ํด ์๋ state๋ ์์๋์ง ์๊ธฐ ๋๋ฌธ์
๋๋ค.
๋ชจ๋ ๋๋๋ง์ ๊ณ ์ ์ ์ดํํธ๋ฅผ ๊ฐ์ง๋ค
์ด ๊ธ์ ๋ถ๋ช ์ดํํธ์ ๋ํด ๋ค๋ฃจ๋ ๊ธ์ธ๋ฐ ์์ง๊น์ง ์ดํํธ ์ด์ผ๊ธฐ๋ฅผ ํ์ง ์์์ฃ ! ๋๋์ด ์ดํํธ๋ฅผ ๋ค๋ฃจ๊ธฐ ์์ํฉ๋๋ค. ์ฌ์ค ์ดํํธ๋ผ๊ณ ๊ทธ๋ค์ง ๋ค๋ฅด์ง ์์ต๋๋ค.
์ด ๋ฌธ์์ ์๋ ์์ ๋ก ๋์๊ฐ ๋ณด๊ฒ ์ต๋๋ค.
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => { document.title = `You clicked ${count} times`; }); return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
์ฌ๊ธฐ์ ํ๋ ์ง๋ฌธ์ ๋๋ฆฌ์ฃ . ์ด๋ป๊ฒ ์ดํํธ๊ฐ ์ต์ ์ count
์ํ๋ฅผ ์ฝ์ด ๋ค์ผ๊น์?
์๋ง๋ ๋ญ๊ฐ โ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉโ ์ด๋ผ๋๊ฐ โ์ต์ ๋ฒโ ๋ผ๋๊ฐ ํ๋๊ฒ ์ดํํธ ํจ์ ์์์ count
์ ์
๋ฐ์ดํธ๋ฅผ ๋ฐ์ํ ๊น์? ์๋๋ฉด count
๋ ๊ฐ๋ณ๊ฐ์ด๋ผ์ ๋ฆฌ์กํธ๊ฐ ์ปดํฌ๋ํธ ์์ ๊ฐ์ ์ง์ ํด์ฃผ๊ณ ์ดํํธ๊ฐ ํญ์ ์ต์ ๊ฐ์ ๋ฐ๋ผ๋ณผ ์ ์๊ฒ ํด ์ฃผ๋ ๊ฑธ๊น์?
์๋๋๋ค.
์ฐ๋ฆฌ๋ ์ด๋ฏธ count
๋ ํน์ ์ปดํฌ๋ํธ ๋๋๋ง์ ํฌํจ๋๋ ์์๋ผ๊ณ ๋ฐฐ์ ์ต๋๋ค. ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ๊ทธ ๋๋๋ง์ โ์ํโ count
์ํ๋ฅผ โ๋ด
๋๋คโ. count
๋ ํน์ ๋ฒ์ ์์ ์ํ๋ ๋ณ์์ด๊ธฐ ๋๋ฌธ์
๋๋ค. ์ดํํธ์๋ ๋๊ฐ์ ๊ฐ๋
์ด ์ ์ฉ๋ฉ๋๋ค!
โ๋ณํํ์ง ์๋โ ์ดํํธ ์์์ count
๋ณ์๊ฐ ์์๋ก ๋ฐ๋๋ค๋ ๋ป์ด ์๋๋๋ค. ์ดํํธ ํจ์ ์์ฒด๊ฐ ๋งค ๋๋๋ง๋ง๋ค ๋ณ๋๋ก ์กด์ฌํฉ๋๋ค.
๊ฐ๊ฐ์ ์ดํํธ ๋ฒ์ ์ ๋งค๋ฒ ๋๋๋ง์ โ์ํโ count
๊ฐ์ โ๋ด
๋๋คโ.
// ์ต์ด ๋๋๋ง ์
function Counter() {
// ...
useEffect(
// ์ฒซ ๋ฒ์งธ ๋๋๋ง์ ์ดํํธ ํจ์ () => { document.title = `You clicked ${0} times`; } );
// ...
}
// ํด๋ฆญํ๋ฉด ํจ์๊ฐ ๋ค์ ํธ์ถ๋๋ค
function Counter() {
// ...
useEffect(
// ๋ ๋ฒ์งธ ๋๋๋ง์ ์ดํํธ ํจ์ () => { document.title = `You clicked ${1} times`; } );
// ...
}
// ๋ ํ๋ฒ ํด๋ฆญํ๋ฉด, ๋ค์ ํจ์๊ฐ ํธ์ถ๋๋ค
function Counter() {
// ...
useEffect(
// ์ธ ๋ฒ์งธ ๋๋๋ง์ ์ดํํธ ํจ์ () => { document.title = `You clicked ${2} times`; } );
// ..
}
๋ฆฌ์กํธ๋ ์ฌ๋ฌ๋ถ์ด ์ ๊ณตํ ์ดํํธ ํจ์๋ฅผ ๊ธฐ์ตํด ๋จ๋ค๊ฐ DOM์ ๋ณํ๋ฅผ ์ฒ๋ฆฌํ๊ณ ๋ธ๋ผ์ฐ์ ๊ฐ ์คํฌ๋ฆฐ์ ๊ทธ๋ฆฌ๊ณ ๋ ๋ค ์คํํฉ๋๋ค.
๋ฐ๋ผ์ ๋น๋ก ์ฐ๋ฆฌ๊ฐ ํ๋์ ๊ฐ๋ ์ผ๋ก ์ดํํธ๋ฅผ ์ด์ผ๊ธฐํ๊ณ ์์ง๋ง(๋ํ๋จผํธ์ ํ์ดํ์ ์ ๋ฐ์ดํธ ํ๋ ๋์), ์ฌ์ค ๋งค ๋๋๋ง ๋ง๋ค ๋ค๋ฅธ ํจ์๋ผ๋ ๋ป์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ฐ๊ฐ์ ์ดํํธ ํจ์๋ ๊ทธ ๋๋๋ง์ โ์ํโ props์ state๋ฅผ โ๋ด ๋๋คโ.
๊ฐ๋ ์ ์ผ๋ก, ์ดํํธ๋ ๋๋๋ง ๊ฒฐ๊ณผ์ ์ผ๋ถ๋ผ ์๊ฐํ ์ ์์ต๋๋ค.
์๊ฒฉํ๊ฒ ์ด์ผ๊ธฐํ์๋ฉด ๊ทธ๋ ์ง ์์ต๋๋ค๋ง(๋ณผํ ์๋ ๋ฌธ๋ฒ์ด๋ ๋ฐํ์ ์ค๋ฒํค๋ ์์ด ํ ์ ์กฐํฉ์ ํ ์ ์๋๋ก ๋ง๋ค๊ธฐ ์ํด), ์ฐ๋ฆฌ๊ฐ ํ์ฑํ๊ณ ์๋ ๋ฉํ ๋ชจ๋ธ ์์์ ์ดํํธ ํจ์๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ฒ๋ผ ํน์ ๋๋๋ง์ ์ํ๋ ํจ์๋ผ๊ณ ์๊ฐํ์๋ฉด ๋ฉ๋๋ค.
๋ ์์ธํ๊ฒ ์ดํดํ ์ ์๋๋ก, ์ฒซ ๋ฒ์งธ ๋๋๋ง์ ๋์ง์ด ๋ณด๊ฒ ์ต๋๋ค.
- ๋ฆฌ์กํธ: state๊ฐ
0
์ผ ๋์ UI๋ฅผ ๋ณด์ฌ์ค. -
์ปดํฌ๋ํธ
- ์ฌ๊ธฐ ๋๋๋ง ๊ฒฐ๊ณผ๋ฌผ๋ก
<p>You clicked 0 times</p>
๊ฐ ์์ด. - ๊ทธ๋ฆฌ๊ณ ๋ชจ๋ ์ฒ๋ฆฌ๊ฐ ๋๋๊ณ ์ด ์ดํํธ๋ฅผ ์คํํ๋ ๊ฒ์ ์์ง ๋ง:
() => { document.title = 'You clicked 0 times' }
.
- ์ฌ๊ธฐ ๋๋๋ง ๊ฒฐ๊ณผ๋ฌผ๋ก
- ๋ฆฌ์กํธ: ์ข์. UI๋ฅผ ์ ๋ฐ์ดํธ ํ๊ฒ ์ด. ์ด๋ด ๋ธ๋ผ์ฐ์ , ๋ DOM์ ๋ญ ์ข ์ถ๊ฐํ๋ ค๊ณ ํด.
- ๋ธ๋ผ์ฐ์ : ์ข์, ํ๋ฉด์ ๊ทธ๋ ค์ค๊ฒ.
-
๋ฆฌ์กํธ: ์ข์ ์ด์ ์ปดํฌ๋ํธ ๋ค๊ฐ ์ค ์ดํํธ๋ฅผ ์คํํ ๊ฑฐ์ผ.
() => { document.title = 'You clicked 0 times' }
๋ฅผ ์คํํ๋ ์ค.
๊ทธ๋ผ ๋ฒํผ์ ํด๋ฆญํ๋ฉด ์ด๋ค ์ผ์ด ๋ฒ์ด์ง๋์ง ๋ณต์ตํด ๋ณด์์ฃ .
- ์ปดํฌ๋ํธ: ์ด๋ด ๋ฆฌ์กํธ, ๋ด ์ํ๋ฅผ
1
๋ก ๋ณ๊ฒฝํด์ค. - ๋ฆฌ์กํธ: ์ํ๊ฐ
1
์ผ๋์ UI๋ฅผ ์ค. -
์ปดํฌ๋ํธ
- ์ฌ๊ธฐ ๋๋๋ง ๊ฒฐ๊ณผ๋ฌผ๋ก
<p>You clicked 1 times</p>
๊ฐ ์์ด. - ๊ทธ๋ฆฌ๊ณ ๋ชจ๋ ์ฒ๋ฆฌ๊ฐ ๋๋๊ณ ์ด ์ดํํธ๋ฅผ ์คํํ๋ ๊ฒ์ ์์ง ๋ง:
() => { document.title = 'You clicked 1 times' }
.
- ์ฌ๊ธฐ ๋๋๋ง ๊ฒฐ๊ณผ๋ฌผ๋ก
- ๋ฆฌ์กํธ: ์ข์. UI๋ฅผ ์ ๋ฐ์ดํธ ํ๊ฒ ์ด. ์ด๋ด ๋ธ๋ผ์ฐ์ , ๋ DOM์ ๋ญ ์ข ์ถ๊ฐํ๋ ค๊ณ ํด.
- ๋ธ๋ผ์ฐ์ : ์ข์, ํ๋ฉด์ ๊ทธ๋ ค์ค๊ฒ.
-
๋ฆฌ์กํธ: ์ข์ ์ด์ ์ปดํฌ๋ํธ ๋ค๊ฐ ์ค ์ดํํธ๋ฅผ ์คํํ ๊ฑฐ์ผ.
() => { document.title = 'You clicked 1 times' }
๋ฅผ ์คํํ๋ ์ค.
๋ชจ๋ ๋๋๋ง์ ๊ณ ์ ์โฆ ๋ชจ๋ ๊ฒ์ ๊ฐ์ง๊ณ ์๋ค
์ด์ ์ดํํธ๋ ๋งค ๋๋๋ง ํ ์คํ๋๋ฉฐ, ๊ทธ๋ฆฌ๊ณ ๊ฐ๋ ์ ์ผ๋ก ์ปดํฌ๋ํธ ๊ฒฐ๊ณผ๋ฌผ์ ์ผ๋ถ๋ก์ ํน์ ๋๋๋ง ์์ ์ prop๊ณผ state๋ฅผ โ๋ณธ๋ค๋โ ๊ฒ์ ์์์ต๋๋ค.
์๊ฐ์ด ๋ง๋์ง ์คํ์ ํด ๋ณด๊ฒ ์ต๋๋ค. ์๋์ ์ฝ๋๋ฅผ ๋ณด์์ฃ .
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => { setTimeout(() => { console.log(`You clicked ${count} times`); }, 3000); }); return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
์ ๊ฐ ์ฝ๊ฐ ๋ธ์ ๋ค์ด๋ฉฐ ๋ฒํผ์ ์ฌ๋ฌ๋ฒ ๋๋ฅธ๋ค๋ฉด ์ด๋ค ์ผ์ด ์ผ์ด๋ ๊น์?
์คํฌ ์ฃผ์
์๋ง ์ด ๋ฌธ์ ๋ ์ผ์ข
์ ํจ์ ์ด๊ณ ๊ฒฐ๊ณผ๋ฌผ์ ์ผ๊ด๋์ง ์์ผ๋ฆฌ๋ผ ์๊ฐํ์
จ๊ฒ ์ง๋ง, ๊ทธ๋ ์ง ์์ต๋๋ค! ๋ก๊ทธ๋ ์์๋๋ก ์ถ๋ ฅ๋ฉ๋๋ค. ๊ฐ๊ฐ์ ํ์ด๋จธ๋ ํน์ ๋๋๋ง์ ์ํ๊ธฐ ๋๋ฌธ์ ๊ทธ ์์ ์ count
๊ฐ์ ๊ฐ์ง๋๋ค. ์ง์ ์คํํด๋ณด์ธ์.
์๋ง โ๋น์ฐํ ์ด๋ ๊ฒ ๋์ํ๊ฒ ์ง! ์ด๋ป๊ฒ ๋ค๋ฅด๊ฒ ๋์ํ๊ฒ ์ด?โ ๋ผ๊ณ ์๊ฐํ์ค ์๋ ์์ต๋๋ค.
๊ธ์์. ํด๋์ค ์ปดํฌ๋ํธ๋ก ๋ง๋ค๋ฉด ์ด๋ ๊ฒ ๋์ํ์ง ์์์ต๋๋ค. ์ด ๋งํฌ์ ํด๋์ค ์ปดํฌ๋ํธ๋ ํจ์ ์ปดํฌ๋ํธ์ ๊ฐ์ ๋์์ ํ๋ฆฌ๋ผ๊ณ ์ฐฉ๊ฐํ๊ธฐ ์ฝ์ต๋๋ค.
componentDidUpdate() {
setTimeout(() => {
console.log(`You clicked ${this.state.count} times`);
}, 3000);
}
ํ์ง๋ง this.state.count
๊ฐ์ ํน์ ๋๋๋ง ์์ ์ ๊ฐ์ด ์๋๋ผ ์ธ์ ๋ ์ต์ ์ ๊ฐ์ ๊ฐ๋ฆฌํต๋๋ค. ๊ทธ๋์ ๋งค๋ฒ 5๊ฐ ์ฐํ์๋ ๋ก๊ทธ๋ฅผ ๋ณด๊ฒ ๋ฉ๋๋ค.
์ ๋ ํ
์ด ์๋ฐ์คํฌ๋ฆฝํธ ํด๋ก์ ์ ์์ฃผ ๋ง์ด ์์กดํ๊ณ ์๋ค๋๊ฒ ์์ด๋ฌ๋ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ด์ ๋ฐํด ํด๋์ค ์ปดํฌ๋ํธ๋ ์ ํต์ ์ผ๋ก ํ์์์์์ ์๋ชป๋ ๊ฐ์ ๊ฐ์ ธ์ค๋ ๋ฌธ์ ์ ์๋ฌ๋ฆฌ๊ณ ์๋๋ฐ ์ด ๋ฌธ์ ๋ ์ฃผ๋ก ํด๋ก์ ์ ์ฐ๊ด์ด ์์ง์. ์๋๋ฉด ์ด ์์์์ ๋ฐ์ํ ์ง์ง ๋ฌธ์ ์ ๊ทผ์์ ํด๋ก์ ์์ฒด๊ฐ ์๋๋ผ ๊ฐ๋ณ๊ฐ ๋ณ๊ฒฝ(mutation)์ด๊ธฐ ๋๋ฌธ์
๋๋ค(๋ฆฌ์กํธ๋ this.state
๊ฐ ์ต์ ์ํ๋ฅผ ๊ฐ๋ฆฌํค๋๋ก ๋ณ๊ฒฝํฉ๋๋ค).
ํด๋ก์ ๋ ์ ๊ทผํ๋ ค๋ ๊ฐ์ด ์ ๋ ๋ฐ๋์ง ์์ ๋ ์ ์ฉํฉ๋๋ค. ๋ฐ๋์ ์์๋ฅผ ์ฐธ์กฐํ๊ณ ์๊ธฐ ๋๋ฌธ์ ์๊ฐ์ ํ๊ธฐ ์ฝ๋๋ก ๋ง๋ค์ด ์ค๋๋ค. ๊ทธ๋ฆฌ๊ณ ์์์ ๋ ผ์ํ ๋๋ก props์ state๋ ํน์ ๋๋๋ง ์์์ ์ ๋ ๋ฐ๋์ง ์์ต๋๋ค. ๊ทธ๋์ ๋ ํด๋ก์ ๋ฅผ ์ฌ์ฉํ์ฌ ์์ ํด๋์ค ์ปดํฌ๋ํธ ์์ ๋ฅผ ๊ณ ์น ์ ์์ต๋๋คโฆ ํด๋ก์ ๋ฅผ ์ด์ฉํด์์.
ํ๋ฆ์ ๊ฑฐ์ฌ๋ฌ ์ฌ๋ผ๊ฐ๊ธฐ
์ด ์์ ์์ ๋ค์ ํ๋ฒ ํฌ๊ฒ ๋ค์ ๊ตฌ์ ์ ์์ด๋ณด๋๊ฒ ์ค์ํฉ๋๋ค. โ์ปดํฌ๋ํธ์ ๋๋๋ง ์์ ์๋ ๋ชจ๋ ํจ์๋ (์ด๋ฒคํธ ํธ๋ค๋ฌ, ์ดํํธ, ํ์์์์ด๋ ๊ทธ ์์์ ํธ์ถ๋๋ API ๋ฑ) ๋๋(render)๊ฐ ํธ์ถ๋ ๋ ์ ์๋ props์ state ๊ฐ์ ์ก์๋๋ค.โ
๋ฐ๋ผ์ ์๋์ ๋ ์์ ๋ ๊ฐ์ต๋๋ค.
function Example(props) {
useEffect(() => {
setTimeout(() => {
console.log(props.counter); }, 1000);
});
// ...
}
function Example(props) {
const counter = props.counter; useEffect(() => {
setTimeout(() => {
console.log(counter); }, 1000);
});
// ...
}
props๋ state๋ฅผ ์ปดํฌ๋ํธ ์์์ ์ผ์ฐ ์ฝ์ด ๋ค์๋์ง ์๋์ง๋ ์๊ด ์์ต๋๋ค. ๊ทธ ๊ฐ๋ค์ ๋ฐ๋์ง ์์ํ ๋๊น์! ํ๋์ ๋๋๋ง ์ค์ฝํ ์์์ props์ state๋ ๋ณํ์ง ์์ ๊ฐ์ผ๋ก ๋จ์์์ต๋๋ค. (๊ฐ๋ค์ ๋ถํด ํ ๋นํ๋ฉด ๋ ํ์คํด์ง๋๋ค.)
๋ฌผ๋ก ๋๋๋ก ์ดํํธ ์์ ์ ์ํด๋ ์ฝ๋ฐฑ์์ ์ฌ์ ์ ์ก์๋ ๊ฐ์ ์ฐ๋ ๊ฒ์ด ์๋๋ผ ์ต์ ์ ๊ฐ์ ์ด์ฉํ๊ณ ์ถ์ ๋๊ฐ ์์ต๋๋ค. ์ ์ผ ์ฌ์ด ๋ฐฉ๋ฒ์ ref๋ฅผ ์ด์ฉํ๋ ๊ฒ์ธ๋ฐ ๋งํฌ์ ๊ธ ๋ง์ง๋ง ๋จ๋ฝ์ ์ค๋ช ๋์ด ์์ต๋๋ค.
๊ณผ๊ฑฐ์ ๋๋๋ง ์์ ์์ ๋ฏธ๋์ props๋ state๋ฅผ ์กฐํํ ํ์๊ฐ ์์ ๋ ์ฃผ์ํ์ ์ผ ํ๋๊ฒ, ์ด๋ฐ ๋ฐฉ์์ ํ๋ฆ์ ๊ฑฐ์ฌ๋ฌ ์ฌ๋ผ๊ฐ๋ ์ผ์ ๋๋ค. ์๋ชป ๋์ง ์์์ง๋ง (์ด๋ค ๊ฒฝ์ฐ์๋ ๋ฐ๋์ ํ์ํ๊ณ ์) ํจ๋ฌ๋ค์์์ ๋ฒ์ด๋๋๊ฒ ๋ โ๊นจ๋ํดโ ๋ณด์ผ ์ ์์ต๋๋ค. ์๋์ ์ฝ๋๋ ์๋์ ์ธ ๊ฒฐ๊ณผ์ธ๋ฐ ํ์ด๋ผ์ดํธ ์ณ๋ ์ฝ๋๋ ํ์ด๋ฐ์ ๋ฏผ๊ฐํ๊ณ ๋ค๋ฃจ๊ธฐ ์ด๋ ต๊ธฐ ๋๋ฌธ์ ๋๋ค. ํด๋์ค ์ปดํฌ๋ํธ๋ผ๋ฉด ์ธ์ ๊ฐ์ ์กฐํํ๋์ง ๋ ๋ช ํํฉ๋๋ค.
์ฌ๊ธฐ ํด๋์ค ์ปดํฌ๋ํธ๋ก ์ผ์ผ์ผฐ๋ ๋์์ ๋ฐ๋ผํด๋ณธ ๋ฒ์ ์ ์นด์ดํฐ ์์ ๊ฐ ์์ต๋๋ค.
function Example() {
const [count, setCount] = useState(0);
const latestCount = useRef(count); useEffect(() => {
// ๋ณ๊ฒฝ ๊ฐ๋ฅํ ๊ฐ์ ์ต์ ์ผ๋ก ์ค์ ํ๋ค
latestCount.current = count; setTimeout(() => { // ๋ณ๊ฒฝ ๊ฐ๋ฅํ ์ต์ ์ ๊ฐ์ ์ฝ์ด ๋ค์ธ๋ค
console.log(`You clicked ${latestCount.current} times`); }, 3000); });
// ...
๋ฆฌ์กํธ๋ก ์ด๋ ํ ๊ฐ์ ์ง์ ๋ณ๊ฒฝํ๋ ๊ฒ์ด ๊บผ๋ฆผ์นํด ๋ณด์
๋๋ค๋ง, ๋ฆฌ์กํธ์ ํด๋์ค ์ปดํฌ๋ํธ๋ ์ ํํ๊ฒ ์ด๋ฐ ์์ผ๋ก this.state
๋ฅผ ์ฌํ ๋นํ๊ณ ์์ต๋๋ค. ๋ฏธ๋ฆฌ ์ก์๋ props ๋ฐ state์๋ ๋ฌ๋ฆฌ ํน์ ์ฝ๋ฐฑ์์ latestCount.current
์ ๊ฐ์ ์ฝ์ด ๋ค์ผ ๋ ์ธ์ ๋ ๊ฐ์ ๊ฐ์ ๋ณด์ฅํ์ง ์์ต๋๋ค. ์ ์๋ ๋ฐ์ ๋ฐ๋ผ ์ด ๊ฐ์ ์ธ์ ๋ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์ด๋ฐ ์ฌ์ฉ ๋ฐฉ๋ฒ์ ๊ธฐ๋ณธ ๋์์ด ์๋๋ฉฐ, ์ฌ๋ฌ๋ถ์ด ์ง์ ๊ฐ์ ธ๋ค ์จ์ผ ํฉ๋๋ค.
๊ทธ๋ฌ๋ฉด ํด๋ฆฐ์ (cleanup)์ ๋ญ์ง?
๋ฌธ์์์ ์ค๋ช ํ ๋๋ก, ์ด๋ค ์ดํํธ๋ ํด๋ฆฐ์ ๋จ๊ณ๋ฅผ ๊ฐ์ง ์๋ ์์ต๋๋ค. ๋ณธ์ง์ ์ผ๋ก ํด๋ฆฐ์ ์ ๋ชฉ์ ์ ๊ตฌ๋ ๊ณผ ๊ฐ์ ์ดํํธ๋ฅผ โ๋๋๋ฆฌ๋โ ๊ฒ์ ๋๋ค.
์๋์ ์ฝ๋๋ฅผ ๋ณด์์ฃ .
useEffect(() => {
ChatAPI.subscribeToFriendStatus(props.id, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.id, handleStatusChange);
};
});
์ฒซ ๋ฒ์งธ ๋๋๋ง์์ prop
์ด {id: 10}
์ด๊ณ , ๋ ๋ฒ์งธ ๋๋๋ง์์ {id: 20}
์ด๋ผ๊ณ ํด ๋ด
์๋ค. ์๋ง๋ ์๋์ ๊ฐ์ ํ๋ฆ๋๋ก ํ๋ฌ๊ฐ๋ฆฌ๋ผ ์๊ฐํ์ค๊ฒ๋๋ค.
- ๋ฆฌ์กํธ๊ฐ
{id: 10}
์ ๋ค๋ฃจ๋ ์ดํํธ๋ฅผ ํด๋ฆฐ์ ํ๋ค. - ๋ฆฌ์กํธ๊ฐ
{id: 20}
์ ๊ฐ์ง๊ณ UI๋ฅผ ๋๋๋งํ๋ค. - ๋ฆฌ์กํธ๊ฐ
{id: 20}
์ผ๋ก ์ดํํธ๋ฅผ ์คํํ๋ค.
(์ค์ ๋ ์กฐ๊ธ ๋ค๋ฆ ๋๋ค)
์์ ๋ฉํ ๋ชจ๋ธ๋๋ก๋ผ๋ฉด, ํด๋ฆฐ์ ์ด ๋ฆฌ๋๋๋ง ๋๊ธฐ ์ ์ ์คํ๋๊ณ ์ด์ ์ prop์ โ๋ณด๊ณ โ, ๊ทธ ๋ค์ ์ ์ดํํธ๊ฐ ๋ฆฌ๋๋๋ง ์ดํ ์คํ๋๊ธฐ ๋๋ฌธ์ ์ prop์ โ๋ณธ๋ค๊ณ โ ์๊ฐํ ์ ์์ต๋๋ค. ์ด ๋ฉํ ๋ชจ๋ธ์ ํด๋์ค์ ๋ผ์ดํ์ฌ์ดํด์ ๊ทธ๋๋ก ์ฎ๊ฒจ ๋์ ๊ฒ๊ณผ ๊ฐ๊ณ , ์ฌ๊ธฐ์๋ ์๋ชป๋ ๋ด์ฉ์ ๋๋ค. ์ ๊ทธ๋ฐ์ง ์์๋ด ์๋ค.
๋ฆฌ์กํธ๋ ๋ธ๋ผ์ฐ์ ๊ฐ ํ์ธํธ ํ๊ณ ๋ ๋ค์์ผ ์ดํํธ๋ฅผ ์คํํฉ๋๋ค. ์ด๋ ๊ฒ ํ์ฌ ๋๋ถ๋ถ์ ์ดํํธ๊ฐ ์คํฌ๋ฆฐ ์ ๋ฐ์ดํธ๋ฅผ ๊ฐ๋ก๋ง์ง ์๊ธฐ ๋๋ฌธ์ ์ฑ์ ๋น ๋ฅด๊ฒ ๋ง๋ค์ด์ค๋๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก ์ดํํธ์ ํด๋ฆฐ์ ๋ ๋ฏธ๋ค์ง๋๋ค. ์ด์ ์ดํํธ๋ ์ prop๊ณผ ํจ๊ป ๋ฆฌ๋๋๋ง ๋๊ณ ๋ ๋ค์ ํด๋ฆฐ์ ๋ฉ๋๋ค.
- ๋ฆฌ์กํธ๊ฐ
{id: 20}
์ ๊ฐ์ง๊ณ UI๋ฅผ ๋๋๋งํ๋ค. - ๋ธ๋ผ์ฐ์ ๊ฐ ์ค์ ๊ทธ๋ฆฌ๊ธฐ๋ฅผ ํ๋ค. ํ๋ฉด ์์์
{id: 20}
์ด ๋ฐ์๋ UI๋ฅผ ๋ณผ ์ ์๋ค. - ๋ฆฌ์กํธ๋
{id: 10}
์ ๋ํ ์ดํํธ๋ฅผ ํด๋ฆฐ์ ํ๋ค. - ๋ฆฌ์กํธ๊ฐ
{id: 20}
์ ๋ํ ์ดํํธ๋ฅผ ์คํํ๋ค.
์ด์ํ๊ฒ ๋๋ ์ ์์ต๋๋ค. ๊ทธ๋ฐ๋ฐ ์ด๋ป๊ฒ prop์ด {id: 20}
์ผ๋ก ๋ฐ๋๊ณ ๋์๋ ์ด์ ์ดํํธ์ ํด๋ฆฐ์
์ด ์ฌ์ ํ ์์ ๊ฐ์ธ {id: 10}
์ โ๋ณด๋โ ๊ฑธ๊น์?
์ ์๋ ๊ฒช์ด ๋ณธ ๊ฒ ๊ฐ๊ตฐ์โฆ ๐ค
์ด์ ๋จ๋ฝ์ ์ธ์ฉํด ๋ณด์๋ฉด
์ปดํฌ๋ํธ๊ฐ ๋๋๋ง ์์ ์๋ ๋ชจ๋ ํจ์๋ (์ด๋ฒคํธ ํธ๋ค๋ฌ, ์ดํํธ, ํ์์์์ด๋ ๊ทธ ์์์ ํธ์ถ๋๋ API ๋ฑ) ๋๋๊ฐ ํธ์ถ๋ ๋ ์ ์๋ props์ state ๊ฐ์ ์ก์๋๋ค.
์ด์ ๋ต์ด ๋ช ํํด์ก๋ค์! ์ด์ฐ๋์๊ฑด ์ดํํธ์ ํด๋ฆฐ์ ์ โ์ต์ โ prop์ ์ฝ์ง ์์ต๋๋ค. ํด๋ฆฐ์ ์ด ์ ์๋ ์์ ์ ๋๋๋ง์ ์๋ ๊ฐ์ ์ฝ๋ ๊ฒ์ ๋๋ค.
// ์ฒซ ๋ฒ์งธ ๋๋๋ง, props๋ {id: 10}
function Example() {
// ...
useEffect(
// ์ฒซ ๋ฒ์งธ ๋๋๋ง์ ์ดํํธ
() => {
ChatAPI.subscribeToFriendStatus(10, handleStatusChange);
// ์ฒซ ๋ฒ์งธ ๋๋๋ง์ ํด๋ฆฐ์
return () => { ChatAPI.unsubscribeFromFriendStatus(10, handleStatusChange); }; }
);
// ...
}
// ๋ค์ ๋๋๋ง, props๋ {id: 20}
function Example() {
// ...
useEffect(
// ๋ ๋ฒ์งธ ๋๋๋ง์ ์ดํํธ
() => {
ChatAPI.subscribeToFriendStatus(20, handleStatusChange);
// ๋ ๋ฒ์งธ ๋๋๋ง์ ํด๋ฆฐ์
return () => {
ChatAPI.unsubscribeFromFriendStatus(20, handleStatusChange);
};
}
);
// ...
}
์๊ตญ์ ํฅ๋ง์ฑ์ ๋ฅผ ๊ฑฐ์น๊ณ , ํด๋ ์๋ช
์ ๋คํ์ฌ ๋ฐฑ์ ์์ฑ์ผ๋ก ๋ณํ ๊ฒ์ด๋ฉฐ, ๋ง์ง๋ง ๋ฌธ๋ช
์ ์ข
๋ง์ ๋ง์ดํ ๊ฒ์
๋๋ค. ํ์ง๋ง ๊ทธ ์ด๋ ํ ๊ฒ๋ ์ฒซ ๋ฒ์งธ ๋๋๋ง์ ํด๋ฆฐ์
์ด ๋ฐ๋ผ๋ณด๋ ๊ฐ์ {id: 10}
์ด์ธ์ ๊ฒ์ผ๋ก ๋ง๋ค ์ ์์ต๋๋ค.
์ด๋ ๊ฒ ๋ฆฌ์กํธ๋ ํ์ธํ ์ดํ ์ดํํธ๋ฅผ ๋ค๋ฃจ๋๊ฒ ๊ธฐ๋ณธ์ด๋ฉฐ ๊ทธ ๊ฒฐ๊ณผ ์ฑ์ ๋น ๋ฅด๊ฒ ๋ง๋ค์ด ์ค๋๋ค. ์ด์ props๋ ์ฐ๋ฆฌ์ ์ฝ๋๊ฐ ์ํ๋ค๋ฉด ๋จ์ ์์ต๋๋ค.
๋ผ์ดํ์ฌ์ดํด์ด ์๋๋ผ ๋๊ธฐํ
์ ๊ฐ ๋ฆฌ์กํธ์์ ์ ์ผ ์ข์ํ๋ ๊ฒ ์ค ํ๋๋ ์ฒ์ ๋๋๋ง ๊ฒฐ๊ณผ๋ฌผ๊ณผ ๊ทธ ์ ๋ฐ์ดํธ๋ฅผ ํตํฉํ์ฌ ํํํ๊ณ ์๋ค๋ ์ ์ ๋๋ค. ์ด๋ก ์ธํด ์ฌ๋ฌ๋ถ์ ํ๋ก๊ทธ๋จ์ ์ํธ๋กํผ๋ฅผ ์ค์ผ ์ ์์ต๋๋ค.
์ ์ปดํฌ๋ํธ๊ฐ ์ด๋ ๊ฒ ์๊ฒผ๋ค๊ณ ํด ๋ณด์ฃ .
function Greeting({ name }) {
return (
<h1 className="Greeting">
Hello, {name}
</h1>
);
}
์ ๊ฐ <Greeting name="Dan" />
์ ๋๋๋ง ํ ๋ค์์ <Greeting name="Yuzhi" />
๋ฅผ ๋๋๋งํ๋์ง, ์์ <Greeting name="Yuzhi" />
๋ง ๋๋๋งํ๋์ง ๋ชจ๋ ๊ฒฝ์ฐ์ ๊ฒฐ๊ณผ๋ โHello, Yuzhiโ ๋ก ๊ฐ์ต๋๋ค.
์ด๋ฐ ๋ง์ด ์์ต๋๋ค. โ๋ชจ๋ ๊ฒ์ ์ฌ์ ์ ๋ฌ๋ ธ์ง ๋ชฉ์ ์ง์ ๋ฌ๋ฆฐ ๊ฒ์ด ์๋๋ผโ ๊ณ ์. ๋ฆฌ์กํธ์ ์์ด์๋ ์ ๋ฐ๋๋ก ์ ์ฉ๋ฉ๋๋ค. ๋ชจ๋ ๊ฒ์ ๋ชฉ์ ์ง์ ๋ฌ๋ ธ์ง ์ฌ์ ์ ๋ฌ๋ฆฐ๊ฒ ์๋๋ค. ์ด๊ฒ jQuery ์ฝ๋์์ $.addClass
, $.removeClass
๋ฅผ ํธ์ถํ๋ ๊ฒ๊ณผ(โ์ฌ์ โ) ๋ฆฌ์กํธ ์ฝ๋์์ ์ด๋ค CSSํด๋์ค๊ฐ ์์ด์ผ ํ๋์ง ์ง์ ํ๋ ๊ฒ์ ์ฐจ์ด์
๋๋ค(โ๋ชฉ์ ์งโ).
๋ฆฌ์กํธ๋ ์ฐ๋ฆฌ๊ฐ ์ง์ ํ props์ state์ ๋ฐ๋ผ DOM๊ณผ ๋๊ธฐํํฉ๋๋ค. ๋๋๋ง ์ โ๋ง์ดํธโ ์ โ์ ๋ฐ์ดํธโ ์ ๊ตฌ๋ถ์ด ์์ต๋๋ค.
์ดํํธ๋ ๊ฐ์ ๋ฐฉ์์ผ๋ก ์๊ฐํ์
์ผ ํฉ๋๋ค. useEffect
๋ ๋ฆฌ์กํธ ํธ๋ฆฌ ๋ฐ๊นฅ์ ์๋ ๊ฒ๋ค์ props์ state์ ๋ฐ๋ผ ๋๊ธฐํ ํ ์ ์๊ฒ ํฉ๋๋ค.
function Greeting({ name }) {
useEffect(() => { document.title = 'Hello, ' + name; }); return (
<h1 className="Greeting">
Hello, {name}
</h1>
);
}
์ ์ฝ๋๋ ์น์ํ ๋ง์ดํธ/์ ๋ฐ์ดํธ/์ธ๋ง์ดํธ ๋ฉํ ๋ชจ๋ธ๊ณผ๋ ๋ฌํ๊ฒ ๋ค๋ฆ ๋๋ค. ๋ค๋ฅด๋ค๋ ๊ฒ์ ๋ง์์์ ๋ด์๋๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ๋ง์ฝ ์ปดํฌ๋ํธ๊ฐ ์ฒซ ๋ฒ์งธ๋ก ๋๋๋งํ ๋์ ๊ทธ ํ์ ๋ค๋ฅด๊ฒ ๋์ํ๋ ์ดํํธ๋ฅผ ์์ฑํ๋ ค๊ณ ํ์ ๋ค๋ฉด, ํ๋ฆ์ ๊ฑฐ์ค๋ฅด๋ ๊ฒ์ ๋๋ค! ๋๋๋ง ๊ฒฐ๊ณผ๋ฌผ์ด โ๋ชฉ์ ์งโ ์ ๋ฐ๋ผ๊ฐ๋ ๊ฒ์ด ์๋๋ผ โ์ฌ์ โ ์ ๋ฐ๋ฅธ๋ค๋ฉด ๋๊ธฐํ์ ์คํจํฉ๋๋ค.
์ปดํฌ๋ํธ๋ฅผ prop A, B, C ์์๋ก ๋๋๋งํ๋์ง, ๋ฐ๋ก C๋ก ๋๋๋งํ๋์ง ๋ณ๋ก ์ ๊ฒฝ์ฐ์ด์ง ์์์ผ ํฉ๋๋ค. ์ ๊น ์ฐจ์ด๊ฐ ์์ ์ ์์ง๋ง(์: ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ฌ ๋), ๊ฒฐ๊ตญ ๋ง์ง๋ง ๊ฒฐ๊ณผ๋ฌผ์ ๊ฐ์์ผ ํฉ๋๋ค.
๋น์ฐํ์ง๋ง ์ฌ์ ํ ๋ชจ๋ ์ดํํธ๋ฅผ ๋งค๋ฒ ๋๋๋ง๋ง๋ค ์คํํ๋ ๊ฒ์ ํจ์จ์ด ๋จ์ด์ง ์ ์์ต๋๋ค. (๊ทธ๋ฆฌ๊ณ ์ด๋ค ๊ฒฝ์ฐ์๋ ๋ฌดํ๋ฃจํ๋ฅผ ์ผ์ผํฌ ์ ์์ง์.)
๊ทธ๋ ๋ค๋ฉด ์ด๋ป๊ฒ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์๊น์?
๋ฆฌ์กํธ์๊ฒ ์ดํํธ๋ฅผ ๋น๊ตํ๋ ๋ฒ์ ๊ฐ๋ฅด์น๊ธฐ
์ฐ๋ฆฌ๋ ์ด๋ฏธ DOM ๊ทธ ์์ฒด์ ๋ํด์๋ ๋ฐฐ์ ์ต๋๋ค. ๋งค๋ฒ์ ๋ฆฌ๋๋๋ง๋ง๋ค DOM ์ ์ฒด๋ฅผ ์๋ก ๊ทธ๋ฆฌ๋ ๊ฒ์ด ์๋๋ผ, ๋ฆฌ์กํธ๊ฐ ์ค์ ๋ก ๋ฐ๋ ๋ถ๋ถ๋ง DOM์ ์ ๋ฐ์ดํธ ํฉ๋๋ค.
์๋์ ์ปดํฌ๋ํธ๋ฅผ
<h1 className="Greeting">
Hello, Dan
</h1>
์ด๋ ๊ฒ ๋ฐ๊พผ๋ค๋ฉด
<h1 className="Greeting">
Hello, Yuzhi
</h1>
๋ฆฌ์กํธ๋ ๋ ๊ฐ์ฒด๋ฅผ ๋น๊ตํฉ๋๋ค.
const oldProps = {className: 'Greeting', children: 'Hello, Dan'};
const newProps = {className: 'Greeting', children: 'Hello, Yuzhi'};
๊ฐ๊ฐ์ prop์ ์ง์ด๋ณด๊ณ children
์ด ๋ฐ๋์ด์ DOM ์
๋ฐ์ดํธ๊ฐ ํ์ํ๋ค๊ณ ํ์
ํ์ง๋ง className
์ ๊ทธ๋ ์ง ์์ต๋๋ค. ๊ทธ๋์ ๊ทธ์ ์๋์ ์ฝ๋๋ง ํธ์ถ๋ฉ๋๋ค.
domNode.innerText = 'Hello, Yuzhi';
// domNode.className ์ ๊ฑด๋๋ฆด ํ์๊ฐ ์๋ค
์ดํํธ์๋ ์ด๋ฐ ๋ฐฉ๋ฒ์ ์ ์ฉํ ์ ์์๊น์? ์ดํํธ๋ฅผ ์ ์ฉํ ํ์๊ฐ ์๋ค๋ฉด ๋ค์ ์คํํ์ง ์๋ ๊ฒ์ด ์ข์ํ ๋ฐ์.
์๋ฅผ ๋ค์ด ์๋ง ์๋์ ์ปดํฌ๋ํธ๋ ์ํ ๋ณํ ๋๋ฌธ์ ๋ค์ ๋๋๋ง ๋ ๊ฒ์ ๋๋ค.
function Greeting({ name }) {
const [counter, setCounter] = useState(0);
useEffect(() => {
document.title = 'Hello, ' + name;
});
return (
<h1 className="Greeting">
Hello, {name}
<button onClick={() => setCounter(count + 1)}> Increment </button> </h1>
);
}
ํ์ง๋ง ์ดํํธ๋ counter
์ํ๊ฐ์ ์ฌ์ฉํ์ง ์์ต๋๋ค. ์ดํํธ๋ document.title
๊ณผ name
prop์ ๋๊ธฐํํ์ง๋ง, name
prop์ ๊ฐ์ต๋๋ค. document.title
์ ๋งค๋ฒ ์นด์ดํฐ ๊ฐ์ด ๋ฐ๋๋๋ง๋ค ์ฌํ ๋นํ๋ ๊ฒ์ ๊ทธ๋ค์ง ์ด์์ ์ผ๋ก ๋ณด์ด์ง ์์ต๋๋ค.
์ข์์, ๊ทธ๋ ๋ค๋ฉดโฆ ๋ฆฌ์กํธ๊ฐ ๊ทธ๋ฅ ์ดํํธ๋ฅผ ๋น๊ตํ๋ฉด ์ ๋ ๊น์?
let oldEffect = () => { document.title = 'Hello, Dan'; };
let newEffect = () => { document.title = 'Hello, Dan'; };
// ๋ฆฌ์กํธ๊ฐ ์ด ๋ฐฐ์ด์ ๊ฐ์ ๋ฐฐ์ด์ด๋ผ๊ณ ์ธ์ํ ์ ์์๊น?
๊ทธ๋ ๊ฒ๋ ์๋๊ฒ ๋ค์. ๋ฆฌ์กํธ๋ ํจ์๋ฅผ ํธ์ถํด๋ณด์ง ์๊ณ ํจ์๊ฐ ์ด๋ค ์ผ์ ํ๋์ง ์์๋ผ ์ ์์ต๋๋ค. (์ ์ฝ๋๋ ํน์ ํ ๊ฐ์ ํฌํจํ๊ณ ์๋ ๊ฒ์ด ์๋๋ผ name
prop์ ์๋ ๊ฒ์ ๋ด์์์ ๋ฟ์
๋๋ค.)
๊ทธ๋์ ํน์ ํ ์ดํํธ๊ฐ ๋ถํ์ํ๊ฒ ๋ค์ ์คํ๋๋ ๊ฒ์ ๋ฐฉ์งํ๊ณ ์ถ๋ค๋ฉด ์์กด์ฑ ๋ฐฐ์ด์(โdepsโ ๋ผ๊ณ ์๋ ค์ง ๋
์์ด์ฃ ) useEffect
์ ์ธ์๋ก ์ ๋ฌํ ์ ์๋ ๊ฒ์
๋๋ค.
useEffect(() => {
document.title = 'Hello, ' + name;
}, [name]); // ์ฐ๋ฆฌ์ ์์กด์ฑ
์ด๊ฑด ๋ง์น ์ฐ๋ฆฌ๊ฐ ๋ฆฌ์กํธ์๊ฒ โ์ด๋ด, ๋ค๊ฐ ์ด ํจ์์ ์์ ๋ณผ ์ ์๋ ๊ฒ์ ์๊ณ ์์ง๋ง, ๋๋๋ง ์ค์ฝํ์์ name
์ธ์ ๊ฐ์ ์ฐ์ง ์๋๋ค๊ณ ์ฝ์ํ ๊ฒ.โ ๋ผ๊ณ ๋งํ๋ ๊ฒ๊ณผ ๊ฐ์ต๋๋ค.
ํ์ฌ์ ์ด์ ์ดํํธ ๋ฐ๋ ์ ์ด ๊ฐ๋ค์ด ๊ฐ๋ค๋ฉด ๋๊ธฐํํ ๊ฒ์ ์์ผ๋ ๋ฆฌ์กํธ๋ ์ดํํธ๋ฅผ ์คํตํ ์ ์์ต๋๋ค.
const oldEffect = () => { document.title = 'Hello, Dan'; };
const oldDeps = ['Dan'];
const newEffect = () => { document.title = 'Hello, Dan'; };
const newDeps = ['Dan'];
// ๋ฆฌ์กํธ๋ ํจ์ ์์ ์ดํด๋ณผ ์ ์์ง๋ง, deps๋ฅผ ๋น๊ตํ ์ ์๋ค.
// ๋ชจ๋ deps๊ฐ ๊ฐ์ผ๋ฏ๋ก, ์ ์ดํํธ๋ฅผ ์คํํ ํ์๊ฐ ์๋ค.
๋๋๋ง ์ฌ์ด์ ์์กด์ฑ ๋ฐฐ์ด ์์ ์๋ ๊ฐ์ด ํ๋๋ผ๋ ๋ค๋ฅด๋ค๋ฉด ์ดํํธ๋ฅผ ์คํตํ ์ ์์ต๋๋ค. ๋ชจ๋ ๊ฒ์ ๋๊ธฐํํด์ผ์ฃ !
๋ฆฌ์กํธ์๊ฒ ์์กด์ฑ์ผ๋ก ๊ฑฐ์ง๋งํ์ง ๋ง๋ผ
์์กด์ฑ์ ๋ํด ๋ฆฌ์กํธ์๊ฒ ๊ฑฐ์ง๋ง์ ํ ๊ฒฝ์ฐ ์ข์ง ์์ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ ธ์ต๋๋ค. ์ง๊ด์ ์ผ๋ก ์ด๊ฒ ๋ง์ ๋ฉ๋๋ค๋ง, ํด๋์ค ์ปดํฌ๋ํธ์ ์ต์ํ ๋ฉํ ๋ชจ๋ธ์ ๊ฐ์ง ๋๋ถ๋ถ์ ์ฌ๋๋ค์ด useEffect
์ ์ธ ๋ ๊ทธ ๊ท์น์ ์ด๊ธฐ๋ ค๋ ๋ชจ์ต์ ๋ดค์ต๋๋ค. (์ฌ์ง์ด ์ ๋ ์ฒ์์๋ ๊ทธ๋ฌ์ด์!)
function SearchResults() {
async function fetchData() {
// ...
}
useEffect(() => {
fetchData();
}, []); // ์ด๊ฒ ๋ง์๊น์? ํญ์ ๊ทธ๋ ์ง ์์ง์. ๊ทธ๋ฆฌ๊ณ ๋ ๋์ ๋ฐฉ์์ผ๋ก ์ฝ๋๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
// ...
}
(Hooks FAQ์์ ๊ทธ ๋์ ์ด๋ป๊ฒ ํด์ผํ๋์ง ์ค๋ช ํฉ๋๋ค. ์์ ์์ ๋ ์๋ซ๋ถ๋ถ์์ ๋ค์ ๋ค๋ฃจ๊ฒ ์ต๋๋ค.)
โํ์ง๋ง ์ ๋ ๋ง์ดํธ ๋ ๋๋ง ์ดํํธ๋ฅผ ์คํํ๊ณ ์ถ๋ค๊ณ ์!โ ๋ผ๊ณ ํ์ค ์ ์์ต๋๋ค. ์ผ๋จ ์ง๊ธ์ deps๋ฅผ ์ง์ ํ๋ค๋ฉด, ์ปดํฌ๋ํธ์ ์๋ ๋ชจ๋ ๊ฐ ์ค ๊ทธ ์ดํํธ์ ์ฌ์ฉ๋ ๊ฐ์ ๋ฐ๋์ ๊ฑฐ๊ธฐ ์์ด์ผ ํ๋ค๋ ๊ฒ์ ๊ธฐ์ตํด ๋์ธ์. props, state, ํจ์๋ค ๋ฑ ์ปดํฌ๋ํธ ์์ ์๋ ๋ชจ๋ ๊ฒ ๋ง์ ๋๋ค.
๊ฐ๋์ ์์ ์ฝ๋์ฒ๋ผ ํ๋ฉด ๋ฌธ์ ๋ฅผ ์ผ์ผํต๋๋ค. ์๋ฅผ ๋ค์ด ๋ฐ์ดํฐ ๋ถ๋ฌ์ค๋ ๋ก์ง์ด ๋ฌดํ ๋ฃจํ์ ๋น ์ง ์๋ ์๊ณ , ์์ผ์ด ๋๋ฌด ์์ฃผ ๋ฐ์ํ ์๋ ์์ต๋๋ค. ์ด๋ฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ์์กด์ฑ์ ์ ๊ฑฐํ๋ ๊ฒ์ด ์๋๋๋ค. ๊ณง ๊ทธ ํด๊ฒฐ์ฑ ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
๋จผ์ ํด๊ฒฐ์ฑ ์ผ๋ก ๋์ด๊ฐ๊ธฐ ์ ์, ์ด ๋ฌธ์ ์ ๋ํด ๋ ์์ธํ ์์๋ด ์๋ค.
์์กด์ฑ์ผ๋ก ๊ฑฐ์ง๋ง์ ํ๋ฉด ์๊ธฐ๋ ์ผ
๋ง์ฝ deps๊ฐ ์ดํํธ์ ์ฌ์ฉํ๋ ๋ชจ๋ ๊ฐ์ ๊ฐ์ง๊ณ ์๋ค๋ฉด, ๋ฆฌ์กํธ๋ ์ธ์ ๋ค์ ์ดํํธ๋ฅผ ์คํํด์ผ ํ ์ง ์๊ณ ์์ต๋๋ค.
useEffect(() => {
document.title = 'Hello, ' + name;
}, [name]);
(์์กด์ฑ์ด ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ์ดํํธ๋ฅผ ๋ค์ ์คํํ๋ค.)
ํ์ง๋ง ๋ง์ฝ ์ดํํธ์ []
๋ฅผ ๋๊ฒจ์ฃผ์๋ค๋ฉด, ์ ์ดํํธ ํจ์๋ ์คํ๋์ง ์์ ๊ฒ์
๋๋ค.
useEffect(() => {
document.title = 'Hello, ' + name;
}, []); // ํ๋ ธ์: deps์ name์ด ์๋ค
(์์กด์ฑ์ด ๊ฐ์ผ๋ฏ๋ก ์ดํํธ๋ ์คํตํ๋ค.)
์ด ๊ฒฝ์ฐ์๋ ๋ฌธ์ ๊ฐ ๋ช ํํด ๋ณด์ผ ์ ์์ต๋๋ค. ํ์ง๋ง ๋ค๋ฅธ ๊ฒฝ์ฐ์ ํด๋์ค ์คํ์ผ์ ํด๊ฒฐ์ฑ ์ด ๊ธฐ์ต์์์ ํ์ด๋์ค๋ฉด ์ด๋ฐ ์ง๊ด์ด ํท๊ฐ๋ฆด ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด ๋งค ์ด๋ง๋ค ์ซ์๊ฐ ์ฌ๋ผ๊ฐ๋ ์นด์ดํฐ๋ฅผ ์์ฑํ๋ค๊ณ ํด ๋ณด๊ฒ ์ต๋๋ค. ํด๋์ค ์ปดํฌ๋ํธ์ ๊ฐ๋
์ ์ ์ฉํ์ ๋ ์ฐ๋ฆฌ์ ์ง๊ด์ โ์ธํฐ๋ฒ์ ํ ๋ฒ๋ง ์ค์ ํ๊ณ , ํ ๋ฒ๋ง ์ ๊ฑฐํ์โ ๊ฐ ๋ฉ๋๋ค. ๊ทธ ์๊ฐ์ ์ฝ๋๋ก ์ฎ๊ธฐ๋ฉด ์ด๋ฐ ์์ ๊ฐ ๋ฉ๋๋ค. ์ด ๋ฉํ ๋ชจ๋ธ์ ๊ฐ์ง๊ณ useEffect
๋ฅผ ์ฌ์ฉํ ์ฝ๋๋ก ๋ณํํ๊ฒ ๋๋ฉด, ์ง๊ด์ ์ผ๋ก deps์ []
๋ฅผ ๋ฃ๊ฒ ๋ฉ๋๋ค. โ์ด๊ฒ ํ๋ฒ๋ง ์คํ๋์ผ๋ฉด ์ข๊ฒ ์ด.โ ๋ผ๊ณ ์. ๊ทธ๋ ์ฃ ?
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
const id = setInterval(() => {
setCount(count + 1);
}, 1000);
return () => clearInterval(id);
}, []); return <h1>{count}</h1>;
}
ํ์ง๋ง ์ด ์์ ๋ ์ซ์๊ฐ ์ค๋ก์ง ํ ๋ฒ๋ง ์ฆ๊ฐํฉ๋๋ค. ์ด์ด์ฟ .
๋ง์ฝ ์ฌ๋ฌ๋ถ์ ๋ฉํ ๋ชจ๋ธ์ด โ์์กด์ฑ ๋ฐฐ์ด์ ๋ด๊ฐ ์ธ์ ์ดํํธ๋ฅผ ๋ค์ ์คํํด์ผ ํ ์ง ์ง์ ํ ๋ ์ฐ์ธ๋ค.โ ๋ผ๋ฉด, ์ ์์ ๋ฅผ ๋ณผ ๋ ์๊ฐ๋น์ฐฉ์ ๋น ์ง ๊ฒ์ ๋๋ค. ์ด๊ฑด ์ธํฐ๋ฒ์ด๋๊น ํ ๋ฒ๋ง ์คํํ๊ณ ์ถ์ฃ . ๊ทธ๋ฐ๋ฐ ์ ์ด๋ฐ ๋ฌธ์ ๊ฐ ์ผ์ด๋ฌ์๊น์?
ํ์ง๋ง ์์กด์ฑ ๋ฐฐ์ด์ด ๋ฆฌ์กํธ์๊ฒ ์ด๋ค ๋๋๋ง ์ค์ฝํ์์ ๋์จ ๊ฐ ์ค ์ดํํธ์ ์ฐ์ด๋ ๊ฒ ์ ๋ถ๋ฅผ ์๋ ค์ฃผ๋ ํํธ๋ผ๊ณ ์ธ์ํ๋ค๋ฉด ๋ง์ด ๋ฉ๋๋ค. count
๋ฅผ ์ฌ์ฉํ์ง๋ง deps ๋ฅผ []
๋ผ๊ณ ์ ์ํ๋ฉด์ ๊ฑฐ์ง๋ง์ ํ์ง์. ์ด ๊ฑฐ์ง๋ง ๋๋ฌธ์ ๋ฒ๊ทธ๊ฐ ํฐ์ง๋ ๊ฒ์ ์๊ฐ ๋ฌธ์ ์
๋๋ค!
์ฒซ ๋ฒ์งธ ๋๋๋ง์์ count
๋ 0
์
๋๋ค. ๋ฐ๋ผ์ ์ฒซ ๋ฒ์งธ ๋๋๋ง์ ์ดํํธ์์ setCount(count + 1)
๋ setCount(0 + 1)
์ด๋ผ๋ ๋ป์ด ๋ฉ๋๋ค. deps ๋ฅผ []
๋ผ๊ณ ์ ์ํ๊ธฐ ๋๋ฌธ์ ์ดํํธ๋ฅผ ์ ๋ ๋ค์ ์คํํ์ง ์๊ณ , ๊ฒฐ๊ตญ ๊ทธ๋ก ์ธํด ๋งค ์ด๋ง๋ค setCount(0 + 1)
์ ํธ์ถํ๋ ๊ฒ์
๋๋ค.
// ์ฒซ ๋ฒ์งธ ๋๋๋ง, state๋ 0
function Counter() {
// ...
useEffect(
// ์ฒซ ๋ฒ์งธ ๋๋๋ง์ ์ดํํธ
() => {
const id = setInterval(() => {
setCount(0 + 1); // ์ธ์ ๋ setCount(1) }, 1000);
return () => clearInterval(id);
},
[] // ์ ๋ ๋ค์ ์คํํ์ง ์๋๋ค );
// ...
}
// ๋งค๋ฒ ๋ค์ ๋๋๋ง๋ง๋ค state๋ 1์ด๋ค
function Counter() {
// ...
useEffect(
// ์ด ์ดํํธ๋ ์ธ์ ๋ ๋ฌด์๋ ๊ฒ // ์๋๋ฉด ๋ฆฌ์กํธ์๊ฒ ๋น deps๋ฅผ ๋๊ฒจ์ฃผ๋ ๊ฑฐ์ง๋ง์ ํ๊ธฐ ๋๋ฌธ () => {
const id = setInterval(() => {
setCount(1 + 1);
}, 1000);
return () => clearInterval(id);
},
[]
);
// ...
}
์ฐ๋ฆฌ๋ ๋ฆฌ์กํธ์๊ฒ ์ด ์ดํํธ๋ ์ปดํฌ๋ํธ ์์ ์๋ ๊ฐ์ ์ฐ์ง ์๋๋ค๊ณ ๊ฑฐ์ง๋ง์ ํ์ต๋๋ค, ์ค์ ๋ก๋ ์ฐ๋๋ฐ๋ ๋ง์ด์ฃ !
์ดํํธ๋ ์ปดํฌ๋ํธ ์์ ์๋ ๊ฐ์ธ(ํ์ง๋ง ์ดํํธ ๋ฐ๊นฅ์ ์๋) count
๊ฐ์ ์ฐ๊ณ ์์ต๋๋ค.
const count = // ...
useEffect(() => {
const id = setInterval(() => {
setCount(count + 1); }, 1000);
return () => clearInterval(id);
}, []);
๋ฐ๋ผ์ []
์ ์์กด์ฑ ๋ฐฐ์ด๋ก ์ง์ ํ๋ ๊ฒ์ ๋ฒ๊ทธ๋ฅผ ๋ง๋ค ๊ฒ์
๋๋ค. ๋ฆฌ์กํธ๋ ๋ฐฐ์ด์ ๋น๊ตํ๊ณ , ์ด ์ดํํธ๋ฅผ ์
๋ฐ์ดํธ ํ์ง ์์ ๊ฒ์
๋๋ค.
(์์กด์ฑ์ด ๊ฐ์ผ๋ฏ๋ก ์ดํํธ๋ ์คํตํ๋ค.)
์ด๋ฐ ์ข ๋ฅ์ ์ด์๋ ํด๊ฒฐ์ฑ ์ ๋ ์ฌ๋ฆฌ๊ธฐ ์ด๋ ต์ต๋๋ค. ๋ฐ๋ผ์ ์ ๋ ์ฌ๋ฌ๋ถ๋ค๊ป ์ธ์ ๋ ์ดํํธ์ ์์กด์ฑ์ ์์งํ๊ฒ ์ ๋ถ ๋ช ์ํ๋ ๊ฒ์ ์ค์ํ ๊ท์น์ผ๋ก ๋ฐ์๋ค์ฌ์ผ ํ๋ค๊ณ ๊ถํฉ๋๋ค. (์ ํฌ๋ ์ฌ๋ฌ๋ถ๋ค์ ํ์ด ์ด ๊ท์น์ ๊ฐ์ ํ๊ธธ ์ํ ๋ ์ธ ์ ์๋ ๋ฆฐํธ ๊ท์น์ ์ ๊ณตํฉ๋๋ค.)
์์กด์ฑ์ ์์งํ๊ฒ ์ ๋ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ
์์กด์ฑ์ ์์งํ๊ฒ ์ ๋๋ฐ ๋ ๊ฐ์ง ์ ๋ต์ด ์์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ์ฒซ ๋ฒ์งธ ๋ฐฉ๋ฒ์ ์ฌ์ฉํด ๋ณด์๊ณ , ํ์ํ๋ค๋ฉด ๋ ๋ฒ์งธ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ์ธ์.
์ฒซ ๋ฒ์งธ ๋ฐฉ๋ฒ์ ์ปดํฌ๋ํธ ์์ ์์ผ๋ฉด์ ์ดํํธ์์ ์ฌ์ฉ๋๋ ๋ชจ๋ ๊ฐ์ด ์์กด์ฑ ๋ฐฐ์ด ์์ ํฌํจ๋๋๋ก ๊ณ ์น๋ ๊ฒ์
๋๋ค. count
๋ฅผ deps์ ์ถ๊ฐํด ๋ณด๊ฒ ์ต๋๋ค.
useEffect(() => {
const id = setInterval(() => {
setCount(count + 1); }, 1000);
return () => clearInterval(id);
}, [count]);
์ด๋ ๊ฒ ์์กด์ฑ ๋ฐฐ์ด์ ์ฌ๋ฐ๋ฅด๊ฒ ๋ง๋ค์์ต๋๋ค. ์ด์์ ์ด์ง ์์ ์ ์์ง๋ง ์ฐ๋ฆฌ๊ฐ ๊ณ ์ณ์ผ ํ๋ ์ฒซ ๋ฒ์งธ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ๊ฒ์
๋๋ค. ์ด์ count
๊ฐ์ ์ดํํธ๋ฅผ ๋ค์ ์คํํ๊ณ ๋งค๋ฒ ๋ค์ ์ธํฐ๋ฒ์์ setCount(count + 1)
๋ถ๋ถ์ ํด๋น ๋๋๋ง ์์ ์ count
๊ฐ์ ์ฌ์ฉํ ๊ฒ๋๋ค.
// ์ฒซ ๋ฒ์งธ ๋๋๋ง, state๋ 0
function Counter() {
// ...
useEffect(
// ์ฒซ ๋ฒ์งธ ๋๋๋ง์ ์ดํํธ
() => {
const id = setInterval(() => {
setCount(0 + 1); // setCount(count + 1) }, 1000);
return () => clearInterval(id);
},
[0] // [count] );
// ...
}
// ๋ ๋ฒ์งธ ๋๋๋ง, state๋ 1
function Counter() {
// ...
useEffect(
// ๋ ๋ฒ์งธ ๋๋๋ง์ ์ดํํธ
() => {
const id = setInterval(() => {
setCount(1 + 1); // setCount(count + 1) }, 1000);
return () => clearInterval(id);
},
[1] // [count] );
// ...
}
์ด๋ ๊ฒ ํ๋ฉด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ฒ ์ง๋ง count
๊ฐ์ด ๋ฐ๋ ๋๋ง๋ค ์ธํฐ๋ฒ์ ํด์ ๋๊ณ ๋ค์ ์ค์ ๋ ๊ฒ์
๋๋ค. ์๋ง ์ํ์ง ์๋ ๋์์ด๊ฒ ์ฃ .
(์์กด์ฑ์ด ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ์ดํํธ๋ฅผ ๋ค์ ์คํํ๋ค)
๋ ๋ฒ์งธ ์ ๋ต์ ์ดํํธ์ ์ฝ๋๋ฅผ ๋ฐ๊ฟ์ ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๊ฒ ๋ณด๋ค ์์ฃผ ๋ฐ๋๋ ๊ฐ์ ์๊ตฌํ์ง ์๋๋ก ๋ง๋๋ ๊ฒ์ ๋๋ค. ์์กด์ฑ์ ๋ํด ๊ฑฐ์ง๋ง์ ํ ํ์๊ฐ ์์ต๋๋ค. ๊ทธ๋ฅ ์์กด์ฑ์ ๋ ์ ๊ฒ ๋๊ฒจ์ฃผ๋๋ก ๋ฐ๊พธ๋ฉด ๋ฉ๋๋ค.
์์กด์ฑ์ ์ ๊ฑฐํ๋ ๋ช ๊ฐ์ง ๊ณตํต์ ์ธ ๊ธฐ์ ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์ดํํธ๊ฐ ์๊ธ์์กฑ ํ๋๋ก ๋ง๋ค๊ธฐ
์ฐ๋ฆฌ๋ ์ดํํธ์ ์์กด์ฑ์์ count
๋ฅผ ์ ๊ฑฐํ๋๋ก ๋ง๋ค๊ณ ์ถ์ต๋๋ค.
useEffect(() => {
const id = setInterval(() => {
setCount(count + 1); }, 1000);
return () => clearInterval(id);
}, [count]);
๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋จผ์ ์์ ์๊ฒ ์ง๋ฌธ์ ํด ๋ด
์๋ค. ๋ฌด์ ๋๋ฌธ์ count
๋ฅผ ์ฐ๊ณ ์๋์? ์ค๋ก์ง setCount
๋ฅผ ์ํด ์ฌ์ฉํ๊ณ ์๋ ๊ฒ์ผ๋ก ๋ณด์
๋๋ค. ์ด ๊ฒฝ์ฐ์ ์ค์ฝํ ์์์ count
๋ฅผ ์ธ ํ์๊ฐ ์ ํ ์์ต๋๋ค. ์ด์ ์ํ๋ฅผ ๊ธฐ์ค์ผ๋ก ์ํ ๊ฐ์ ์
๋ฐ์ดํธ ํ๊ณ ์ถ์ ๋๋, setState
์ ํจ์ ํํ์ ์
๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
useEffect(() => {
const id = setInterval(() => {
setCount(c => c + 1); }, 1000);
return () => clearInterval(id);
}, []);
์ ๋ ์ด๋ฐ ๊ฒฝ์ฐ๋ฅผ โ์๋ชป๋ ์์กด๊ด๊ณโ ๋ผ๊ณ ์๊ฐํ๋ ๊ฒ์ ์ข์ํฉ๋๋ค. ๋ค, count
๋ ์ฐ๋ฆฌ๊ฐ setCount(count + 1)
์ด๋ผ๊ณ ์ผ๊ธฐ ๋๋ฌธ์ ์ดํํธ ์์์ ํ์ํ ์์กด์ฑ์ด์์ต๋๋ค. ํ์ง๋ง ์ง์ง๋ก ์ฐ๋ฆฌ๋ count
๋ฅผ count + 1
๋ก ๋ณํํ์ฌ ๋ฆฌ์กํธ์๊ฒ โ๋๋ ค์ฃผ๊ธฐ ์ํดโ ์ํ์ ๋ฟ์
๋๋ค. ํ์ง๋ง ๋ฆฌ์กํธ๋ ํ์ฌ์ count
๋ฅผ ์ด๋ฏธ ์๊ณ ์์ต๋๋ค. ์ฐ๋ฆฌ๊ฐ ๋ฆฌ์กํธ์๊ฒ ์๋ ค์ค์ผ ํ๋ ๊ฒ์ ์ง๊ธ ๊ฐ์ด ๋ญ๋ ๊ฐ์ ์ํ ๊ฐ์ ํ๋ ๋ํ๋ผ๋ ๊ฒ์
๋๋ค.
๊ทธ๊ฒ ์ ํํ setCount(c => c +1)
์ด ์๋ํ๋ ๊ฒ์
๋๋ค. ๋ฆฌ์กํธ์๊ฒ ์ํ๊ฐ ์ด๋ป๊ฒ ๋ฐ๋์ด์ผ ํ๋์ง โ์ง์นจ์ ๋ณด๋ด๋ ๊ฒโ ์ด๋ผ๊ณ ์๊ฐํ ์ ์์ต๋๋ค. ์ด โ์
๋ฐ์ดํฐ ํํโ ๋ํ ๋ค๋ฅธ ์ผ์ด์ค์์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ์ฌ๋ฌ ๊ฐ์ ์
๋ฐ์ดํธ๋ฅผ ๋ฌถ์ด์ ์ฒ๋ฆฌํ ๋์ฒ๋ผ์.
*์์กด์ฑ์ ์ ๊ฑฐํ์ง ์๊ณ ๋ ์ค์ ๋ก *๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค๋ ๊ฒ์ ์์๋์
์ผ ํฉ๋๋ค. ๊ผผ์๋ฅผ ์ฐ์ง ์์์ต๋๋ค. ์ดํํธ๋ ๋ ์ด์ ๋๋๋ง ์ค์ฝํ์์ count
๊ฐ์ ์ฝ์ด ๋ค์ด์ง ์์ต๋๋ค.
(์์กด์ฑ์ ๊ฐ์ผ๋ฏ๋ก ์ดํํธ๋ ์คํตํ๋ค.)
์ฌ๊ธฐ์ ์คํํด๋ณผ ์ ์์ต๋๋ค.
์ด ์ดํํธ๊ฐ ํ ๋ฒ๋ง ์คํ๋์๋ค ํ๋๋ผ๋, ์ฒซ ๋ฒ์งธ ๋๋๋ง์ ํฌํจ๋๋ ์ธํฐ๋ฒ ์ฝ๋ฐฑ์ ์ธํฐ๋ฒ์ด ์คํ๋ ๋๋ง๋ค c => c + 1
์ด๋ผ๋ ์
๋ฐ์ดํธ ์ง์นจ์ ์ ๋ฌํ๋๋ฐ ์๋ฒฝํ๊ฒ ๋ค์ด๋ง์ต๋๋ค. ๋ ์ด์ ํ์ฌ์ count
์ํ๋ฅผ ์๊ณ ์์ ํ์๊ฐ ์์ต๋๋ค. ๋ฆฌ์กํธ๊ฐ ์ด๋ฏธ ์๊ณ ์์ผ๋๊น์.
ํจ์ํ ์ ๋ฐ์ดํธ์ ๊ตฌ๊ธ ๋ฅ์ค(Google Docs)
์ด๋ป๊ฒ ๋๊ธฐํ๊ฐ ์ดํํธ์ ๋ฉํ ๋ชจ๋ธ์ด ๋๋์ง ์ค๋ช ํ๋์ง ๊ธฐ์ตํ์๋์? ๋๊ธฐํ์ ๋ํด ์๊ฐํ ๋ ํฅ๋ฏธ๋ก์ด ๋ถ๋ถ์ ์ข ์ข ์์คํ ๊ฐ์ โ๋ฉ์ธ์งโ๋ฅผ ์ํ์ ์ฎ์ด์ง ์์ ์ฑ๋ก ์ ์งํ๊ณ ์ถ์ ๋๊ฐ ์๋ค๋ ๊ฒ์ ๋๋ค. ์๋ฅผ ๋ค์ด ๊ตฌ๊ธ ๋ฅ์ค์์ ๋ฌธ์๋ฅผ ํธ์งํ๋ ๊ฒ์ ์ค์ ๋ก ์๋ฒ๋ก ์ ์ฒด ํ์ด์ง๋ฅผ ๋ณด๋ด๋ ๊ฒ์ด ์๋๋๋ค. ๊ทธ๋ ๋ค๋ฉด ๊ต์ฅํ ๋นํจ์จ์ ์ด๊ฒ ์ฃ . ๊ทธ ๋์ ์ฌ์ฉ์๊ฐ ๋ฌด์์ ํ๊ณ ์ ํ๋์ง ํํํ ๊ฒ์ ๋ณด๋ ๋๋ค.
์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๋ ๋ค๋ฅด๊ฒ ์ง๋ง ์ดํํธ์๋ ๊ฐ์ ์ฒ ํ์ด ์ ์ฉ๋ฉ๋๋ค. ์ค๋ก์ง ํ์ํ ์ต์ํ์ ์ ๋ณด๋ฅผ ์ดํํธ ์์์ ์ปดํฌ๋ํธ๋ก ์ ๋ฌํ๋๊ฒ ์ต์ ํ์ ๋์์ด ๋ฉ๋๋ค. setCount(c => c + 1)
๊ฐ์ ์
๋ฐ์ดํฐ ํํ๋ setCount(count + 1)
๋ณด๋ค ๋ช
๋ฐฑํ ์ ์ ์ ๋ณด๋ฅผ ์ ๋ฌํฉ๋๋ค. ํ์ฌ์ ์นด์ดํธ ๊ฐ์ โ์ค์ผ๋์งโ ์๊ธฐ ๋๋ฌธ์
๋๋ค. ๊ทธ์ ํ์(โ์ฆ๊ฐโ)๋ฅผ ํํํ ๋ฟ์
๋๋ค. ๋ฆฌ์กํธ๋ก ์๊ฐํ๊ธฐ ๋ฌธ์์ ์ต์ํ์ ์ํ๋ฅผ ์ฐพ์ผ๋ผ๋ ๋ด์ฉ์ด ํฌํจ๋์ด ์์ต๋๋ค. ๊ทธ ๋ฌธ์์ ์ฐ์ธ ๊ฒ๊ณผ ๊ฐ์ ์์น์ด์ง๋ง ์
๋ฐ์ดํธ์ ํด๋น๋๋ค๊ณ ์๊ฐํ์ธ์.
(๊ฒฐ๊ณผ๋ณด๋ค) ์๋๋ฅผ ์ธ์ฝ๋ฉํ๋ ๊ฒ์ ๊ตฌ๊ธ ๋ฅ์ค๊ฐ ํ๋ ํธ์ง ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ๋ฐฉ๋ฒ๊ณผ ์ ์ฌํฉ๋๋ค. ์กฐ๊ธ ๊ณผ์ฅ์ผ ์๋ ์์ง๋ง, ํจ์ํ ์ ๋ฐ์ดํธ ๋ฐฉ์๋ ๋ฆฌ์กํธ ์์์ ๋น์ทํ ์ญํ ์ ํ๊ณ ์์ต๋๋ค. ์ฌ๋ฌ ์์ค์์ ์ด๋ฃจ์ด์ง๋ ์ ๋ฐ์ดํธ๊ฐ (์ด๋ฒคํธ ํธ๋ค๋ฌ, ์ดํํธ ๊ตฌ๋ ๋ฑ) ์์ธก ๊ฐ๋ฅํ ๋ฐฉ์์ผ๋ก ๋ชจ์ฌ์ ์ ํํ ์ ์ฉ๋ ์ ์๋๋ก ๋ณด์ฅํฉ๋๋ค.
ํ์ง๋ง setCount(c => c + 1)
์กฐ์ฐจ๋ ๊ทธ๋ฆฌ ์ข์ ๋ฐฉ๋ฒ์ ์๋๋๋ค. ์ข ์ด์ํด ๋ณด์ด๊ธฐ๋ ํ๊ณ ํ ์ ์๋ ์ผ์ด ๊ต์ฅํ ์ ํ์ ์
๋๋ค. ์๋ฅผ ๋ค์ด ์๋ก์๊ฒ ์์กดํ๋ ๋ ์ํ ๊ฐ์ด ์๊ฑฐ๋ prop ๊ธฐ๋ฐ์ผ๋ก ๋ค์ ์ํ๋ฅผ ๊ณ์ฐํ ํ์๊ฐ ์์ ๋๋ ๋์์ด ๋์ง ์์ต๋๋ค. ๋คํํ๋ setCount(c => c + 1)
์ ๋ ๊ฐ๋ ฅํ ์๋งค ํจํด์ด ์์ต๋๋ค. ๋ฐ๋ก useReducer
์
๋๋ค.
์ก์ ์ ์ ๋ฐ์ดํธ๋ก๋ถํฐ ๋ถ๋ฆฌํ๊ธฐ
์ด์ ์ ์์ ๋ฅผ count
์ step
๋ ๊ฐ์ง ์ํ ๋ณ์๋ฅผ ๊ฐ์ง๋ ๊ฒ์ผ๋ก ๋ฐ๊ฟ๋ณด๊ฒ ์ต๋๋ค. ์ธํฐ๋ฒ์ step
์
๋ ฅ๊ฐ์ ๋ฐ๋ผ count
๊ฐ์ ๋ํ ๊ฒ์
๋๋ค.
function Counter() {
const [count, setCount] = useState(0);
const [step, setStep] = useState(1);
useEffect(() => {
const id = setInterval(() => {
setCount(c => c + step); }, 1000);
return () => clearInterval(id);
}, [step]); return (
<>
<h1>{count}</h1>
<input value={step} onChange={e => setStep(Number(e.target.value))} />
</>
);
}
(์ฌ๊ธฐ ๋ฐ๋ชจ๊ฐ ์์ต๋๋ค.)
์ด๊ฑด ๊ผผ์๊ฐ ์๋๋ผ๋ ๊ฒ์ ์์๋์ธ์. ์ ๊ฐ step
์ ์ดํํธ ์์์ ์ฌ์ฉํ๊ณ ์๊ธฐ ๋๋ฌธ์ ์์กด์ฑ ๋ฐฐ์ด์ ์ถ๊ฐํด ๋์์ต๋๋ค. ๊ทธ๋์ ์ฝ๋๋ ์ ํํ๊ฒ ๋์๊ฐ๋๋ค.
์ด ์์ ์ ํ์ฌ ๋์์ step
์ด ๋ณ๊ฒฝ๋๋ฉด ์ธํฐ๋ฒ์ ๋ค์ ์์ํ๋ ๊ฒ์
๋๋ค. ์๋๋ฉด ์์กด์ฑ์ผ๋ก ์ ์๋์ด ์์ผ๋๊น์. ๊ทธ๋ฆฌ๊ณ ๋ง์ ๊ฒฝ์ฐ์ ์ด๊ฒ ์ ํํ ์ฌ๋ฌ๋ถ์ด ์ํ๋ ๋์์ผ ๊ฒ๋๋ค! ์ดํํธ๋ฅผ ๋ถํดํ๊ณ ์๋ก ์ค์ ํ๋๋ฐ๋ ์๋ฌด ๋ฌธ์ ๊ฐ ์๊ณ , ํน๋ณํ ์ข์ ์ด์ ๊ฐ ์์ง ์๋ค๋ฉด ๋ถํดํ๋ ๊ฒ์ ํผํ์ง ๋ง์์ผ ํฉ๋๋ค.
ํ์ง๋ง step
์ด ๋ฐ๋๋ค๊ณ ์ธํฐ๋ฒ ์๊ณ๊ฐ ์ด๊ธฐํ๋์ง ์๋ ๊ฒ์ ์ํ๋ค๋ฉด ์ด๋ป๊ฒ ๋ ๊น์? ์ดํํธ์ ์์กด์ฑ ๋ฐฐ์ด์์ step
์ ์ ๊ฑฐํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผํ ๊น์?
์ด๋ค ์ํ ๋ณ์๊ฐ ๋ค๋ฅธ ์ํ ๋ณ์์ ํ์ฌ ๊ฐ์ ์ฐ๊ด๋๋๋ก ์ค์ ํ๋ ค๊ณ ํ๋ค๋ฉด, ๋ ์ํ ๋ณ์ ๋ชจ๋ useReducer
๋ก ๊ต์ฒดํด์ผ ํ ์ ์์ต๋๋ค.
setSomething(something => ...)
๊ฐ์ ์ฝ๋๋ฅผ ์์ฑํ๊ณ ์๋ค๋ฉด, ๋์ ๋ฆฌ๋์๋ฅผ ์จ๋ณด๋ ๊ฒ์ ๊ณ ๋ คํ๊ธฐ ์ข์ ํ์ด๋ฐ์
๋๋ค. ๋ฆฌ๋์๋ ์ปดํฌ๋ํธ์์ ์ผ์ด๋๋ โ์ก์
โ์ ํํ๊ณผ ๊ทธ ๋ฐ์์ผ๋ก ์ํ๊ฐ ์ด๋ป๊ฒ ์
๋ฐ์ดํธ๋์ด์ผ ํ ์ง๋ฅผ ๋ถ๋ฆฌํฉ๋๋ค.
์ดํํธ ์์์ step
์์กด์ฑ์ dispatch
๋ก ๋ฐ๊พธ์ด ๋ณด๊ฒ ์ต๋๋ค.
const [state, dispatch] = useReducer(reducer, initialState);const { count, step } = state;
useEffect(() => {
const id = setInterval(() => {
dispatch({ type: 'tick' }); // setCount(c => c + step) ๋์ ์ }, 1000);
return () => clearInterval(id);
}, [dispatch]);
(๋ฐ๋ชจ๋ฅผ ๋ณด์ธ์.)
์๋ง โ์ด๊ฒ ๋ญ๊ฐ ๋ ์ข์์?โ ๋ผ๊ณ ๋ฌผ์ด๋ณด์ค ์ ์์ต๋๋ค. ๋ฆฌ์กํธ๋ ์ปดํฌ๋ํธ๊ฐ ์ ์ง๋๋ ํ dispatch
ํจ์๊ฐ ํญ์ ๊ฐ๋ค๋ ๊ฒ์ ๋ณด์ฅํฉ๋๋ค. ๋ฐ๋ผ์ ์์ ์์ ์์ ์ธํฐ๋ฒ์ ๋ค์ ๊ตฌ๋
ํ ํ์์กฐ์ฐจ ์์ต๋๋ค.
๋ฌธ์ ๊ฐ ํด๊ฒฐ๋๋ค์!
(๋ฆฌ์กํธ๊ฐ dispatch
, setState
, useRef
์ปจํ
์ด๋ ๊ฐ์ด ํญ์ ๊ณ ์ ๋์ด ์๋ค๋ ๊ฒ์ ๋ณด์ฅํ๋๊น ์์กด์ฑ ๋ฐฐ์ด์์ ๋บ ์๋ ์์ต๋๋ค. ํ์ง๋ง ๋ช
์ํ๋ค๊ณ ํด์ ๋์ ๊ฒ์ ์์ต๋๋ค.)
์ดํํธ ์์์ ์ํ๋ฅผ ์ฝ๋ ๋์ ๋ฌด์จ ์ผ์ด ์ผ์ด๋ฌ๋์ง ์๋ ค์ฃผ๋ ์ ๋ณด๋ฅผ ์ธ์ฝ๋ฉํ๋ ์ก์
์ ๋์คํจ์นํฉ๋๋ค. ์ด๋ ๊ฒ ํ์ฌ ์ดํํธ๋ step
์ํ๋ก๋ถํฐ ๋ถ๋ฆฌ๋์ด ์๊ฒ ๋ฉ๋๋ค. ์ดํํธ๋ ์ด๋ป๊ฒ ์ํ๋ฅผ ์
๋ฐ์ดํธ ํ ์ง ์ ๊ฒฝ์ฐ์ง ์๊ณ , ๋จ์ง ๋ฌด์จ ์ผ์ด ์ผ์ด๋ฌ๋์ง ์๋ ค์ค๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฆฌ๋์๊ฐ ์
๋ฐ์ดํธ ๋ก์ง์ ๋ชจ์๋ก๋๋ค.
const initialState = {
count: 0,
step: 1,
};
function reducer(state, action) {
const { count, step } = state;
if (action.type === 'tick') { return { count: count + step, step }; } else if (action.type === 'step') {
return { count, step: action.step };
} else {
throw new Error();
}
}
(์์์ ๋์ณค๋ค๋ฉด ์ฌ๊ธฐ ๋ฐ๋ชจ๊ฐ ์์ต๋๋ค.)
์ useReducer๊ฐ Hooks์ ์นํธ ๋ชจ๋์ธ๊ฐ
์ฐ๋ฆฌ๋ ์ดํํธ๊ฐ ์ด์ ์ํ๋ฅผ ๊ธฐ์ค์ผ๋ก ์ํ๋ฅผ ์ค์ ํ ํ์๊ฐ ์์ ๋ ์ด๋ป๊ฒ ์์กด์ฑ์ ์ ๊ฑฐํ๋์ง ์ดํด๋ดค์ต๋๋ค. ํ์ง๋ง ๋ค์ ์ํ๋ฅผ ๊ณ์ฐํ๋๋ฐ props ๊ฐ ํ์ํ๋ค๋ฉด ์ด๋จ๊น์? ์๋ฅผ ๋ค์ด API๊ฐ <Count step={1} />
์ธ๊ฑฐ์ฃ . ๋น์ฐํ์ง๋ง ์ด๋ด ๋ ์์กด์ฑ์ผ๋ก props.step
์ ์ค์ ํ๋ ๊ฒ์ ํผํ ์ ์๊ฒ ์ฃ ?
์ฌ์ค์ ํผํ ์ ์์ด์! ๋ฆฌ๋์ ๊ทธ ์์ฒด๋ฅผ ์ปดํฌ๋ํธ ์์ ์ ์ํ์ฌ props๋ฅผ ์ฝ๋๋ก ํ๋ฉด ๋ฉ๋๋ค.
function Counter({ step }) { const [count, dispatch] = useReducer(reducer, 0);
function reducer(state, action) {
if (action.type === 'tick') {
return state + step; } else {
throw new Error();
}
}
useEffect(() => {
const id = setInterval(() => {
dispatch({ type: 'tick' });
}, 1000);
return () => clearInterval(id);
}, [dispatch]);
return <h1>{count}</h1>;
}
์ด ํจํด์ ๋ช ๊ฐ์ง ์ต์ ํ๋ฅผ ๋ฌดํจํํ๊ธฐ ๋๋ฌธ์ ์ด๋์๋ ์ฐ์ง ๋ง์ธ์. ํ์ง๋ง ํ์ํ๋ค๋ฉด ์ด๋ ๊ฒ ๋ฆฌ๋์ ์์์ props์ ์ ๊ทผํ ์ ์์ต๋๋ค. (์ฌ๊ธฐ ๋ฐ๋ชจ๊ฐ ์์ต๋๋ค.)
์ด ๊ฒฝ์ฐ์กฐ์ฐจ ๋๋๋ง๊ฐ dispatch
์ ๋์ผ์ฑ์ ์ฌ์ ํ ๋ณด์ฅ๋ฉ๋๋ค. ๊ทธ๋์ ์ํ๋ค๋ฉด ์ดํํธ์ ์์กด์ฑ ๋ฐฐ์ด์์ ๋นผ๋ฒ๋ฆด ์๋ ์์ต๋๋ค. ์ดํํธ๊ฐ ์ฌ์คํ๋๋๋ก ๋ง๋ค์ง ์์ํ
๋๊น์.
์๋ง ์ด๋ ๊ฒ ์๊ฐํ์ค ์๋ ์์ต๋๋ค. โ์ด๊ฒ ์ด๋ป๊ฒ ๊ฐ๋ฅํ์ง? ์ด๋ป๊ฒ ๋ค๋ฅธ ๋๋๋ง์ ํฌํจ๋ ์ดํํธ ์์์ ํธ์ถ๋ ๋ฆฌ๋์๊ฐ props๋ฅผ โ์๊ณ โ ์์ง?โ ๋ต์ dispatch
๋ฅผ ํ ๋์ ์์ต๋๋ค. ๋ฆฌ์กํธ๋ ๊ทธ์ ์ก์
์ ๊ธฐ์ตํด ๋์ต๋๋ค. ํ์ง๋ง ๋ค์ ๋๋๋ง ์ค์ ๋ฆฌ๋์๋ฅผ ํธ์ถํ ๊ฒ์
๋๋ค. ์ด ์์ ์์ ์ props๊ฐ ์ค์ฝํ ์์ผ๋ก ๋ค์ด์ค๊ณ ์ดํํธ ๋ด๋ถ์๋ ์๊ด์ด ์๊ฒ ๋์ฃ .
์ด๋์ ์ ๊ฐ useReducer
๋ฅผ Hooks์ โ์นํธ ๋ชจ๋โ ๋ผ๊ณ ์๊ฐํ๋ ๊ฒ์
๋๋ค. ์
๋ฐ์ดํธ ๋ก์ง๊ณผ ๊ทธ๋ก ์ธํด ๋ฌด์์ด ์ผ์ด๋๋์ง ์์ ํ๋ ๊ฒ์ ๋ถ๋ฆฌํ ์ ์๋๋ก ๋ง๋ค์ด์ค๋๋ค. ๊ทธ ๋ค์์ ์ดํํธ์ ๋ถํ์ํ ์์กด์ฑ์ ์ ๊ฑฐํ์ฌ ํ์ํ ๋๋ณด๋ค ๋ ์์ฃผ ์คํ๋๋ ๊ฒ์ ํผํ ์ ์๋๋ก ๋์์ค๋๋ค.
ํจ์๋ฅผ ์ดํํธ ์์ผ๋ก ์ฎ๊ธฐ๊ธฐ
ํํ ์ค์ ์ค ํ๋๊ฐ ํจ์๋ ์์กด์ฑ์ ํฌํจ๋๋ฉด ์๋๋ค๋ ๊ฒ์ ๋๋ค. ์๋ฅผ ๋ค์ด ์ด ์ฝ๋๋ ๋์ํ๋ ๊ฒ ์ฒ๋ผ ๋ณด์ ๋๋ค.
function SearchResults() {
const [data, setData] = useState({ hits: [] });
async function fetchData() {
const result = await axios(
'https://hn.algolia.com/api/v1/search?query=react',
);
setData(result.data);
}
useEffect(() => {
fetchData();
}, []); // ์ด๊ฑฐ ๊ด์ฐฎ์๊ฐ? // ...
(์ด ์์ ๋ Robin Wieruch์ ๋ฉ์ง ๊ธ์์ ์ฐจ์ฉํ ๊ฒ์ ๋๋ค. ์ดํด๋ณด์ธ์!)
์ผ๋จ ์ด ์ฝ๋๋ ๋์ํฉ๋๋ค. ํ์ง๋ง ๊ฐ๋จํ ๋ก์ปฌ ํจ์๋ฅผ ์์กด์ฑ์์ ์ ์ธํ๋ ํด๊ฒฐ์ฑ ์ ์ปดํฌ๋ํธ๊ฐ ์ปค์ง๋ฉด์ ๋ชจ๋ ๊ฒฝ์ฐ๋ฅผ ๋ค๋ฃจ๊ณ ์๋์ง ๋ณด์ฅํ๊ธฐ ์์ฃผ ํ๋ค๋ค๋ ๋ฌธ์ ๊ฐ ์์ต๋๋ค!
๊ฐ ํจ์๊ฐ 5๋ฐฐ์ ๋๋ ์ปค์ ธ์ ์ฝ๋๋ฅผ ์ด๋ฐ ๋ฐฉ์์ผ๋ก ๋๋์๋ค๊ณ ์๊ฐํด ๋ด ์๋ค.
function SearchResults() {
// ์ด ํจ์๊ฐ ๊ธธ๋ค๊ณ ์์ํด ๋ด
์๋ค
function getFetchUrl() {
return 'https://hn.algolia.com/api/v1/search?query=react';
}
// ์ด ํจ์๋ ๊ธธ๋ค๊ณ ์์ํด ๋ด
์๋ค
async function fetchData() {
const result = await axios(getFetchUrl());
setData(result.data);
}
useEffect(() => {
fetchData();
}, []);
// ...
}
์ด์ ๋์ค์ ์ด ํจ์๋ค ์ค์ ํ๋๊ฐ state๋ prop์ ์ฌ์ฉํ๋ค๊ณ ์๊ฐํด ๋ด ์๋ค.
function SearchResults() {
const [query, setQuery] = useState('react');
// ์ด ํจ์๊ฐ ๊ธธ๋ค๊ณ ์์ํด ๋ด
์๋ค
function getFetchUrl() {
return 'https://hn.algolia.com/api/v1/search?query=' + query; }
// ์ด ํจ์๊ฐ ๊ธธ๋ค๊ณ ์์ํด ๋ด
์๋ค
async function fetchData() {
const result = await axios(getFetchUrl());
setData(result.data);
}
useEffect(() => {
fetchData();
}, []);
// ...
}
๋ง์ฝ ์ด๋ฐ ํจ์๋ฅผ ์ฌ์ฉํ๋ ์ด๋ ํ ์ดํํธ์๋ deps๋ฅผ ์ ๋ฐ์ดํธํ๋ ๊ฒ์ ๊น๋นกํ๋ค๋ฉด(์๋ง๋ ๋ค๋ฅธ ํจ์๋ฅผ ํตํด์์!), ์ดํํธ๋ prop๊ณผ state์ ๋ณํ์ ๋๊ธฐํํ๋๋ฐ ์คํจํ ๊ฒ์ ๋๋ค. ๊ทธ๋ค์ง ์ข์ง ์๋ค์.
๋คํํ๋, ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ฌ์ด ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. ์ด๋ ํ ํจ์๋ฅผ ์ดํํธ ์์์๋ง ์ด๋ค๋ฉด, ๊ทธ ํจ์๋ฅผ ์ง์ ์ดํํธ ์์ผ๋ก ์ฎ๊ธฐ์ธ์.
function SearchResults() {
// ...
useEffect(() => {
// ์๊น์ ํจ์๋ค์ ์์ผ๋ก ์ฎ๊ฒผ์ด์! function getFetchUrl() { return 'https://hn.algolia.com/api/v1/search?query=react'; } async function fetchData() { const result = await axios(getFetchUrl()); setData(result.data); } fetchData();
}, []); // โ
Deps๋ OK
// ...
}
(์ฌ๊ธฐ ๋ฐ๋ชจ๊ฐ ์์ต๋๋ค.)
์ด๋ฌ๋ฉด ๋ญ๊ฐ ์ข์์ง๋๊ตฌ์? ์ฐ๋ฆฌ๋ ๋ ์ด์ โ์ฎ๊ฒจ์ง๋ ์์กด์ฑโ ์ ์ ๊ฒฝ ์ธ ํ์๊ฐ ์์ต๋๋ค. ์์กด์ฑ ๋ฐฐ์ด์ ๋ ์ด์ ๊ฑฐ์ง๋ง ํ์ง ์์ต๋๋ค. ์ง์ง๋ก ์ดํํธ ์์์ ์ปดํฌ๋ํธ์ ๋ฒ์ ๋ฐ๊นฅ์ ์๋ ๊ทธ ์ด๋ ํ ๊ฒ๋ ์ฌ์ฉํ์ง ์๊ณ ์์ต๋๋ค.
๋์ค์ getFetchUrl
์ ์์ ํ๊ณ query
state๋ฅผ ์จ์ผํ๋ค๊ณ ํ๋ฉด, ์ดํํธ ์์ ์๋ ํจ์๋ง ๊ณ ์น๋ฉด ๋๋ค๋ ๊ฒ์ ์ฌ์ด ๋ฐ๊ฒฌํ ์ ์์ต๋๋ค. ๊ฑฐ๊ธฐ์ ๋ํด query
๋ฅผ ์ดํํธ์ ์์กด์ฑ์ผ๋ก ์ถ๊ฐํด์ผ๊ฒ ์ง์.
function SearchResults() {
const [query, setQuery] = useState('react');
useEffect(() => {
function getFetchUrl() {
return 'https://hn.algolia.com/api/v1/search?query=' + query; }
async function fetchData() {
const result = await axios(getFetchUrl());
setData(result.data);
}
fetchData();
}, [query]); // โ
Deps๋ OK // ...
}
(์ฌ๊ธฐ ๋ฐ๋ชจ์ ๋๋ค.)
์ด ์์กด์ฑ์ ๋ํ๋ ๊ฒ์ด ๋จ์ํ โ๋ฆฌ์กํธ๋ฅผ ๋ฌ๋๋โ ๊ฒ์ ์๋๋๋ค. query
๊ฐ ๋ฐ๋ ๋ ๋ฐ์ดํฐ๋ฅผ ๋ค์ ํ์นญํ๋ ๊ฒ์ด ๋ง์ด ๋ฉ๋๋ค. useEffect
์ ๋์์ธ์ ์ฌ์ฉ์๊ฐ ์ ํ์ ์ฌ์ฉํ๋ค ๊ฒช์ ๋๊น์ง ๋ฌด์ํ๋ ๋์ , ๋ฐ์ดํฐ ํ๋ฆ์ ๋ณํ๋ฅผ ์์์ฐจ๋ฆฌ๊ณ ์ดํํธ๊ฐ ์ด๋ป๊ฒ ๋๊ธฐํํด์ผํ ์ง ์ ํํ๋๋ก ๊ฐ์ ํฉ๋๋ค.
eslint-plugin-react-hooks
ํ๋ฌ๊ทธ์ธ์ exhaustive-deps
๋ฆฐํธ ๋ฃฐ ๋๋ถ์, ์๋ํฐ์์ ์ฝ๋๋ฅผ ์์ฑํ๋ฉด์ ์ดํํธ๋ฅผ ๋ถ์ํ๊ณ ์ด๋ค ์์กด์ฑ์ด ๋น ์ ธ ์๋์ง ์ ์์ ๋ฐ์ ์ ์๊ฒ ๋์์ต๋๋ค. ๋ค๋ฅด๊ฒ ์ด์ผ๊ธฐํ์๋ฉด ์ปดํฌ๋ํธ ์์์ ์ด๋ค ๋ฐ์ดํฐ ํ๋ฆ์ ๋ณํ๊ฐ ์ ๋๋ก ์ฒ๋ฆฌ๋์ง ์๊ณ ์๋์ง ์ปดํจํฐ๊ฐ ์๋ ค์ค ์ ์๋ค๋๊ฑฐ์ฃ .
๊ฝค ์ข์ง์.
ํ์ง๋ง ์ ๋ ์ด ํจ์๋ฅผ ์ดํํธ ์์ ๋ฃ์ ์ ์์ด์
๋๋๋ก ํจ์๋ฅผ ์ดํํธ ์์ ์ฎ๊ธฐ๊ณ ์ถ์ง ์์ ์๋ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ํ ์ปดํฌ๋ํธ์์ ์ฌ๋ฌ๊ฐ์ ์ดํํธ๊ฐ ์๋๋ฐ ๊ฐ์ ํจ์๋ฅผ ํธ์ถํ ๋, ๋ก์ง์ ๋ณต๋ถํ๊ณ ์ถ์ง ์๊ฒ ์ฃ . ์๋๋ฉด prop ๋๋ฌธ์ด๊ฑฐ๋์.
์ด๋ฐ ํจ์๋ฅผ ์ดํํธ์ ์์กด์ฑ์ผ๋ก ์ ์ํ์ง ๋ง์์ผ ํ ๊น์? ๊ทธ๋ ๊ฒ ์๊ฐํ์ง ์์ต๋๋ค. ๋ค์ ๋งํ์๋ฉด, ์ดํํธ๋ ์์ ์ ์์กด์ฑ์ ๋ํด ๊ฑฐ์ง๋ง์ ํ๋ฉด ์๋ฉ๋๋ค. ๋ณดํต์ ๋ ๋์ ํด๊ฒฐ์ฑ ์ด ์์ต๋๋ค. ํํ ์คํด ์ค ํ๋๊ฐ โํจ์๋ ์ ๋ ๋ฐ๋์ง ์๋๋คโ ์ ๋๋ค. ํ์ง๋ง ์ด ๊ธ์ ํตํด ๋ฐฐ์ ๋ฏ, ๊ทธ ๋ง์ด ์ง์ค๋ก๋ถํฐ ์ผ๋ง๋ ๋ฉ๋ฆฌ ๋จ์ด์ ธ์๋์ง ์ ์ ์์ต๋๋ค. ์ฌ์ค์, ์ปดํฌ๋ํธ ์์ ์ ์๋ ํจ์๋ ๋งค ๋๋๋ง๋ง๋ค ๋ฐ๋๋๋ค!
ํ์ง๋ง ๊ทธ๋ก ์ธํด ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค. ๋ ์ดํํธ๊ฐ getFetchUrl
์ ํธ์ถํ๋ค๊ณ ์๊ฐํด๋ด
์๋ค.
function SearchResults() {
function getFetchUrl(query) {
return 'https://hn.algolia.com/api/v1/search?query=' + query;
}
useEffect(() => {
const url = getFetchUrl('react');
// ... ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์์ ๋ฌด์ธ๊ฐ๋ฅผ ํ๋ค ...
}, []); // ๐ด ๋น ์ง dep: getFetchUrl
useEffect(() => {
const url = getFetchUrl('redux');
// ... ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์์ ๋ฌด์ธ๊ฐ๋ฅผ ํ๋ค ...
}, []); // ๐ด ๋น ์ง dep: getFetchUrl
// ...
}
์ด ๊ฒฝ์ฐ getFetchUrl
์ ๊ฐ๊ฐ์ ์ดํํธ ์์ผ๋ก ์ฎ๊ธฐ๊ฒ ๋๋ฉด ๋ก์ง์ ๊ณต์ ํ ์ ์์ผ๋ ๊ทธ๋ค์ง ๋ฌ๊ฐ์ง ์์ต๋๋ค. ๋ ์ดํํธ ๋ชจ๋ (๋งค ๋๋๋ง๋ง๋ค ๋ฐ๋๋) getFetchUrl
์ ๊ธฐ๋๊ณ ์์ผ๋, ์์กด์ฑ ๋ฐฐ์ด๋ ์ธ๋ชจ๊ฐ ์์ต๋๋ค.
function SearchResults() {
// ๐ด ๋งค๋ฒ ๋๋๋ง๋ง๋ค ๋ชจ๋ ์ดํํธ๋ฅผ ๋ค์ ์คํํ๋ค function getFetchUrl(query) { return 'https://hn.algolia.com/api/v1/search?query=' + query; } useEffect(() => {
const url = getFetchUrl('react');
// ... ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์์ ๋ฌด์ธ๊ฐ๋ฅผ ํ๋ค ...
}, [getFetchUrl]); // ๐ง Deps๋ ๋ง์ง๋ง ๋๋ฌด ์์ฃผ ๋ฐ๋๋ค
useEffect(() => {
const url = getFetchUrl('redux');
// ... ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์์ ๋ฌด์ธ๊ฐ๋ฅผ ํ๋ค ...
}, [getFetchUrl]); // ๐ง Deps๋ ๋ง์ง๋ง ๋๋ฌด ์์ฃผ ๋ฐ๋๋ค
// ...
}
๊ตฌ๋ฏธ๊ฐ ๋น๊ธฐ๋ ํด๊ฒฐ์ฑ
์ ๊ทธ๋ฅ getFetchUrl
ํจ์๋ฅผ ์์กด์ฑ ๋ฐฐ์ด์์ ๋นผ ๋ฒ๋ฆฌ๋ ๊ฒ์
๋๋ค. ํ์ง๋ง ์ ๋ ์ข์ ๋ฐฉ๋ฒ์ด๋ผ ์๊ฐํ์ง ์์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ฐ๋ฆฌ๊ฐ ์ธ์ ์ดํํธ์ ์ํด ๋ค๋ฃจ์ด์ง ํ์๊ฐ ์๋ ๋ฐ์ดํฐ ํ๋ฆ์ ๋ณํ๋ฅผ ๋ํด์ผ ํ ์ง ์์์ฐจ๋ฆฌ๊ธฐ ์ด๋ ค์์ง๋๋ค.
๋์ ๋ ๊ฐ๋จํ ํด๊ฒฐ์ฑ ์ด ๋ ๊ฐ ์์ต๋๋ค.
๋จผ์ , ํจ์๊ฐ ์ปดํฌ๋ํธ ์ค์ฝํ ์์ ์ด๋ ํ ๊ฒ๋ ์ฌ์ฉํ์ง ์๋๋ค๋ฉด, ์ปดํฌ๋ํธ ์ธ๋ถ๋ก ๋์ด์ฌ๋ ค๋๊ณ ์ดํํธ ์์์ ์์ ๋กญ๊ฒ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
// โ
๋ฐ์ดํฐ ํ๋ฆ์ ์ํฅ์ ๋ฐ์ง ์๋๋คfunction getFetchUrl(query) { return 'https://hn.algolia.com/api/v1/search?query=' + query;}function SearchResults() {
useEffect(() => {
const url = getFetchUrl('react');
// ... ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์์ ๋ฌด์ธ๊ฐ๋ฅผ ํ๋ค ...
}, []); // โ
Deps๋ OK
useEffect(() => {
const url = getFetchUrl('redux');
// ... ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์์ ๋ฌด์ธ๊ฐ๋ฅผ ํ๋ค ...
}, []); // โ
Deps๋ OK
// ...
}
์ ํจ์๋ ๋๋๋ง ์ค์ฝํ์ ํฌํจ๋์ด์์ง ์์ผ๋ฉฐ ๋ฐ์ดํฐ ํ๋ฆ์ ์ํฅ์ ๋ฐ์ ์ ์๊ธฐ ๋๋ฌธ์ deps์ ๋ช ์ํ ํ์๊ฐ ์์ต๋๋ค. ์ฐ์ฐํ๋ผ๋ props๋ state๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
ํน์ useCallback
ํ
์ผ๋ก ๊ฐ์ ์ ์์ต๋๋ค.
function SearchResults() {
// โ
์ฌ๊ธฐ ์ ์๋ deps๊ฐ ๊ฐ๋ค๋ฉด ํญ๋ฑ์ฑ์ ์ ์งํ๋ค const getFetchUrl = useCallback((query) => { return 'https://hn.algolia.com/api/v1/search?query=' + query; }, []); // โ
์ฝ๋ฐฑ์ deps๋ OK useEffect(() => {
const url = getFetchUrl('react');
// ... ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์์ ๋ฌด์ธ๊ฐ๋ฅผ ํ๋ค ...
}, [getFetchUrl]); // โ
์ดํํธ์ deps๋ OK
useEffect(() => {
const url = getFetchUrl('redux');
// ... ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์์ ๋ฌด์ธ๊ฐ๋ฅผ ํ๋ค ...
}, [getFetchUrl]); // โ
์ดํํธ์ deps๋ OK
// ...
}
useCallback
์ ์์กด์ฑ ์ฒดํฌ์ ๋ ์ด์ด๋ฅผ ํ๋ ๋ ๋ํ๋ ๊ฒ์
๋๋ค. ๋ฌ๋ฆฌ ๋งํด ๋ฌธ์ ๋ฅผ ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ํด๊ฒฐํ๋๋ฐ, ํจ์์ ์์กด์ฑ์ ํผํ๊ธฐ๋ณด๋ค ํจ์ ์์ฒด๊ฐ ํ์ํ ๋๋ง ๋ฐ๋ ์ ์๋๋ก ๋ง๋๋ ๊ฒ์
๋๋ค.
์ด ์ ๊ทผ๋ฐฉ์์ด ์ ์ ์ฉํ์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค. ์๊น ์์ ๋ 'react'
, 'redux'
๋ผ๋ ๋ ๊ฐ์ง ๊ฒ์ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ฌ์ฃผ์์ต๋๋ค. ํ์ง๋ง ์
๋ ฅ์ ๋ฐ๋ ๋ถ๋ถ์ ์ถ๊ฐํ์ฌ ์์์ query
๋ฅผ ๊ฒ์ํ ์ ์๋ค๊ณ ํด ๋ด
์๋ค. ๊ทธ๋์ query
๋ฅผ ์ธ์๋ก ๋ฐ๋ ๋์ , getFetchUrl
์ด ์ง์ญ ์ํ๋ก๋ถํฐ ์ด๋ฅผ ์ฝ์ด๋ค์
๋๋ค.
๊ทธ๋ ๊ฒ ์์ ํ๋ฉด ์ฆ์ query
์์กด์ฑ์ด ๋น ์ ธ์๋ค๋ ์ฌ์ค์ ํ์
ํ๊ฒ ๋ฉ๋๋ค.
function SearchResults() {
const [query, setQuery] = useState('react');
const getFetchUrl = useCallback(() => { // No query argument
return 'https://hn.algolia.com/api/v1/search?query=' + query;
}, []); // ๐ด ๋น ์ง ์์กด์ฑ: query // ...
}
์ ๊ฐ useCallback
์ deps์ query
๋ฅผ ํฌํจํ๋๋ก ๊ณ ์น๋ฉด, getFetchUrl
์ ์ฌ์ฉํ๋ ์ด๋ ํ ์ดํํธ๋ผ๋ query
๊ฐ ๋ฐ๋ ๋๋ง๋ค ๋ค์ ์คํ๋ ๊ฒ์
๋๋ค.
function SearchResults() {
const [query, setQuery] = useState('react');
// โ
query๊ฐ ๋ฐ๋ ๋๊น์ง ํญ๋ฑ์ฑ์ ์ ์งํ๋ค const getFetchUrl = useCallback(() => { return 'https://hn.algolia.com/api/v1/search?query=' + query; }, [query]); // โ
์ฝ๋ฐฑ deps๋ OK useEffect(() => {
const url = getFetchUrl();
// ... ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์์ ๋ฌด์ธ๊ฐ๋ฅผ ํ๋ค ...
}, [getFetchUrl]); // โ
์ดํํธ์ deps๋ OK
// ...
}
useCallback
๋๋ถ์ query
๊ฐ ๊ฐ๋ค๋ฉด, getFetchUrl
๋ํ ๊ฐ์ ๊ฒ์ด๋ฉฐ, ์ดํํธ๋ ๋ค์ ์คํ๋์ง ์์ ๊ฒ์
๋๋ค. ํ์ง๋ง ๋ง์ฝ query
๊ฐ ๋ฐ๋๋ค๋ฉด, getFetchUrl
๋ํ ๋ฐ๋๋ฉฐ, ๋ฐ์ดํฐ๋ฅผ ๋ค์ ํ์นญํ ๊ฒ์
๋๋ค. ๋ง์น ์์
์คํ๋ ๋์ํธ์์ ์ด๋ค ์
์ ๋ฐ๊พธ๋ฉด ๋ค๋ฅธ ์
์ด ์๋์ผ๋ก ๋ค์ ๊ณ์ฐ๋๋ ๊ฒ๊ณผ ๋น์ทํฉ๋๋ค.
์ด๊ฒ์ ๊ทธ์ ๋ฐ์ดํฐ ํ๋ฆ๊ณผ ๋๊ธฐํ์ ๋ํ ๊ฐ๋ ์ ๋ฐ์๋ค์ธ ๊ฒฐ๊ณผ์ ๋๋ค. ๋ถ๋ชจ๋ก๋ถํฐ ํจ์ prop์ ๋ด๋ ค๋ณด๋ด๋ ๊ฒ ๋ํ ๊ฐ์ ํด๊ฒฐ์ฑ ์ด ์ ์ฉ๋ฉ๋๋ค.
function Parent() {
const [query, setQuery] = useState('react');
// โ
query๊ฐ ๋ฐ๋ ๋๊น์ง ํญ๋ฑ์ฑ์ ์ ์งํ๋ค const fetchData = useCallback(() => { const url = 'https://hn.algolia.com/api/v1/search?query=' + query; // ... ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์์ ๋ฆฌํดํ๋ค ... }, [query]); // โ
์ฝ๋ฐฑ deps๋ OK return <Child fetchData={fetchData} />
}
function Child({ fetchData }) {
let [data, setData] = useState(null);
useEffect(() => {
fetchData().then(setData);
}, [fetchData]); // โ
์ดํํธ deps๋ OK
// ...
}
fetchData
๋ ์ค๋ก์ง Parent
์ query
์ํ๊ฐ ๋ฐ๋ ๋๋ง ๋ณํ๊ธฐ ๋๋ฌธ์, Child
์ปดํฌ๋ํธ๋ ์ฑ์ ๊ผญ ํ์ํ ๋๊ฐ ์๋๋ผ๋ฉด ๋ฐ์ดํฐ๋ฅผ ๋ค์ ํ์นญํ์ง ์์ ๊ฒ์
๋๋ค.
ํจ์๋ ๋ฐ์ดํฐ ํ๋ฆ์ ์ผ๋ถ์ธ๊ฐ?
ํฅ๋ฏธ๋กญ๊ฒ๋ ์ด ํจํด์ ํด๋์ค ์ปดํฌ๋ํธ์์ ์ฌ์ฉํ๋ฉด ์ ๋๋ก ๋์ํ์ง ์๋๋ฐ, ์ด๊ฒ ์ดํํธ์ ๋ผ์ดํ์ฌ์ดํด ํจ๋ฌ๋ค์์ ๊ฒฐ์ ์ ์ธ ์ฐจ์ด๋ฅผ ๋ณด์ฌ์ค๋๋ค. ์์ ์ฝ๋๋ฅผ ํด๋์ค ์ปดํฌ๋ํธ๋ก ์นํํด๋ดค๋ค๊ณ ์นฉ์๋ค.
class Parent extends Component {
state = {
query: 'react'
};
fetchData = () => { const url = 'https://hn.algolia.com/api/v1/search?query=' + this.state.query; // ... ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์์ ๋ฌด์ธ๊ฐ๋ฅผ ํ๋ค ... }; render() {
return <Child fetchData={this.fetchData} />;
}
}
class Child extends Component {
state = {
data: null
};
componentDidMount() { this.props.fetchData(); } render() {
// ...
}
}
์๋ง๋ ์ด๋ฐ ์๊ฐ์ ํ์ค๊ฒ๋๋ค. โ์ด๋ด์ ๋, ์ด์ ์ฐ๋ฆฌ ๋ชจ๋ useEffect
๋ componentDidMount
์ componentDidUpdate
๊ฐ ์์ธ ๊ฒ์ด๋ผ๋ ๊ฒ์ ์๊ณ ์์ด์. ์ด๋ ๊ฒ ๊ณ์ ๋ท๋ถ์ ์น ํ์๋ ์๋ค๊ตฌ์!โ ํ์ง๋ง ์ด ๋ก์ง์ componentDidUpdate
์์ ๋์ํ์ง ์์ต๋๋ค.
class Child extends Component {
state = {
data: null
};
componentDidMount() {
this.props.fetchData();
}
componentDidUpdate(prevProps) { // ๐ด ์ด ์กฐ๊ฑด๋ฌธ์ ์ ๋ ์ฐธ์ด ๋ ์ ์๋ค if (this.props.fetchData !== prevProps.fetchData) { this.props.fetchData(); } } render() {
// ...
}
}
๋น์ฐํ๋ fetchData
๋ ํด๋์ค ๋ฉ์๋์
๋๋ค! (์๋๋ฉด ํด๋์ค ์์ฑ์ด๋ผ๊ณ ๋งํ ์ ์์ง๋ง ๋ฑํ ๋ฌ๋ผ์ง๋ ๊ฒ์ ์์ต๋๋ค.) state๊ฐ ๋ฐ๋์๋ค๊ณ ์ ๋ฉ์๋๊ฐ ๋ฌ๋ผ์ง์ง ์์ต๋๋ค. ๋ฐ๋ผ์ this.props.fetchData
๋ prevProps.fetchData
์ ๊ฐ๊ธฐ ๋๋ฌธ์ ์ ๋ ๋ค์ ๋ฐ์ดํฐ๋ฅผ ํ์นญํ์ง ์์ต๋๋ค. ๊ทธ๋ ๋ค๋ฉด ์๊น ์กฐ๊ฑด๋ฌธ์ ์ ๊ฑฐํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น์?
componentDidUpdate(prevProps) {
this.props.fetchData();
}
์ด ์ ๊น๋ง์, ์ด๋ ๊ฒ ํ๋ฉด ๋งค๋ฒ ๋ค์ ๋๋๋ง ํ ๋๋ง๋ค ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ฌํ
๋ฐ์. (์์ ๋ด์ฉ์ ์ปดํฌ๋ํธ ํธ๋ฆฌ์ ๋ฃ๊ณ ์ ๋๋ฉ์ด์
์ ์ถ๊ฐํด์ฃผ๋ฉด ๊ฝค ์ฌ๋ฐ์ ๊ฒ๋๋ค.) ํน์ ํน์ ํ query
๋ฅผ ๋ฐ์ธ๋ฉํด๋๋ฉด ์ด๋จ๊น์?
render() {
return <Child fetchData={this.fetchData.bind(this, this.state.query)} />;
}
ํ์ง๋ง ์ด๋ ๊ฒ ํ๋ฉด query
๊ฐ ๋ฐ๋์ง ์์๋๋ฐ๋ this.props.fetchData !== prevProps.fetchData
๋ ์ธ์ ๋ true
๊ฐ ๋ ๊ฒ์
๋๋ค! ๊ฒฐ๊ตญ ๋งค๋ฒ ๋ฐ์ดํฐ๋ฅผ ๋ค์ ํ์นญํ๊ฒ ์ฃ .
์ง์ง ํด๋์ค ์ปดํฌ๋ํธ๋ก ์ด ์์๊ป๋ผ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ์ด ๊ฝ ๊นจ๋ฌผ๊ณ query
์์ฒด๋ฅผ Child
์ปดํฌ๋ํธ์ ๋๊ธฐ๋ ๊ฒ ๋ฟ์
๋๋ค. Child
์ปดํฌ๋ํธ๊ฐ query
๋ฅผ ์ง์ ์ฌ์ฉํ์ง ์์์๋ ๋ถ๊ตฌํ๊ณ query
๊ฐ ๋ฐ๋ ๋ ๋ค์ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๋ ๋ก์ง์ ํด๊ฒฐํ ์ ์์ต๋๋ค.
class Parent extends Component {
state = {
query: 'react'
};
fetchData = () => {
const url = 'https://hn.algolia.com/api/v1/search?query=' + this.state.query;
// ... ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์์ ๋ฌด์ธ๊ฐ๋ฅผ ํ๋ค ...
};
render() {
return <Child fetchData={this.fetchData} query={this.state.query} />; }
}
class Child extends Component {
state = {
data: null
};
componentDidMount() {
this.props.fetchData();
}
componentDidUpdate(prevProps) {
if (this.props.query !== prevProps.query) { this.props.fetchData(); } }
render() {
// ...
}
}
์ ๋ ๋์ ๋ฆฌ์กํธ์ ํด๋์ค ์ปดํฌ๋ํธ๋ฅผ ๋ค๋ค ์ค๋ฉด์, ๋ถํ์ํ prop์ ๋ด๋ ค๋ณด๋ด๋ฉด์ ๋ถ๋ชจ ์ปดํฌ๋ํธ์ ์บก์ํ๋ฅผ ๊นจํธ๋ฆฌ๋ ์ผ์ ์ต์ํด์ก์ต๋๋ค. ๊ทธ๋ฌ๋ค ์ง๋ ์ฃผ๊ฐ ๋์ด์์ผ ์ ๊ทธ๋์ผ ํ๋์ง ๊นจ๋ฌ์์ต๋๋ค.
ํด๋์ค ์ปดํฌ๋ํธ์์, ํจ์ prop ์์ฒด๋ ์ค์ ๋ก ๋ฐ์ดํฐ ํ๋ฆ์์ ์ฐจ์งํ๋ ๋ถ๋ถ์ด ์์ต๋๋ค. ๋ฉ์๋๋ ๊ฐ๋ณ์ฑ์ด ์๋ this
๋ณ์์ ๋ฌถ์ฌ ์๊ธฐ ๋๋ฌธ์ ํจ์์ ์ผ๊ด์ฑ์ ๋ด๋ณดํ ์ ์๊ฒ ๋ฉ๋๋ค. ๊ทธ๋ฌ๋ฏ๋ก ์ฐ๋ฆฌ๊ฐ ํจ์๋ง ํ์ํ ๋๋ โ์ฐจ์ดโ ๋ฅผ ๋น๊ตํ๊ธฐ ์ํด ์จ๊ฐ ๋ค๋ฅธ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํด์ผ ํ์ต๋๋ค. ๋ถ๋ชจ ์ปดํฌ๋ํธ๋ก๋ถํฐ ๋ด๋ ค์จ this.props.fetchData
๊ฐ ์ด๋ค ์ํ์ ๊ธฐ๋๊ณ ์๋์ง, ์๋๋ฉด ๊ทธ๋ฅ ์ํ๊ฐ ๋ฐ๋๊ธฐ๋ง ํ ๊ฒ์ธ์ง ์ ์๊ฐ ์์ต๋๋ค.
useCallback
์ ์ฌ์ฉํ๋ฉด, ํจ์๋ ๋ช
๋ฐฑํ๊ฒ ๋ฐ์ดํฐ ํ๋ฆ์ ํฌํจ๋ฉ๋๋ค. ๋ง์ฝ ํจ์์ ์
๋ ฅ๊ฐ์ด ๋ฐ๋๋ฉด ํจ์ ์์ฒด๊ฐ ๋ฐ๋๊ณ , ๋ง์ฝ ๊ทธ๋ ์ง ์๋ค๋ฉด ๊ฐ์ ํจ์๋ก ๋จ์์๋ค๊ณ ๋ง ํ ์ ์์ต๋๋ค. ์ธ๋ฐํ๊ฒ ์ ๊ณต๋๋ useCallback
๋๋ถ์ props.fetchData
๊ฐ์ props ๋ณํ๋ ์๋์ ์ผ๋ก ํ์ ์ปดํฌ๋ํธ๋ก ์ ๋ฌ๋ฉ๋๋ค.
๋น์ทํ๊ฒ, useMemo
๋ํ ๋ณต์กํ ๊ฐ์ฒด์ ๋ํด ๊ฐ์ ๋ฐฉ์์ ํด๊ฒฐ์ฑ
์ ์ ๊ณตํฉ๋๋ค.
function ColorPicker() {
// color๊ฐ ์ง์ง๋ก ๋ฐ๋์ง ์๋ ํ
// Child์ ์์ props ๋น๊ต๋ฅผ ๊นจํธ๋ฆฌ์ง ์๋๋ค
const [color, setColor] = useState('pink');
const style = useMemo(() => ({ color }), [color]);
return <Child style={style} />;
}
๊ทธ๋ ๋ค๊ณ useCallback
์ ์ด๋๋ ์ง ์ฌ์ฉํ๋ ๊ฒ์ ๊ฝค ํฌ๋ฐํ ๋ฐฉ๋ฒ์ด๋ผ๊ณ ๊ฐ์กฐํ๊ณ ์ถ์ต๋๋ค. useCallback
์ ๊ฝค ์ข์ ๋ํ๊ตฌ์ด๋ฉฐ ํจ์๊ฐ ์ ๋ฌ๋์ด ์์ ์ปดํฌ๋ํธ์ ์ดํํธ ์์์ ํธ์ถ๋๋ ๊ฒฝ์ฐ ์ ์ฉํฉ๋๋ค. ์๋๋ฉด ์์ ์ปดํฌ๋ํธ์ ๋ฉ๋ชจ์ด์ ์ด์
์ด ๊นจ์ง์ง ์๋๋ก ๋ฐฉ์งํ ๋๋ ์ฐ์
๋๋ค. ํ์ง๋ง ํ
์์ฒด๊ฐ ์ฝ๋ฐฑ์ ๋ด๋ ค๋ณด๋ด๋ ๊ฒ์ ํผํ๋ ๋ ์ข์ ๋ฐฉ๋ฒ์ ํจ๊ป ์ ๊ณตํฉ๋๋ค.
์์ ์์ ๋ผ๋ฉด ์ ๋ fetchData
๋ฅผ ์ดํํธ ์์ ๋๊ฑฐ๋(์ปค์คํ
ํ
์ผ๋ก ์ถ์ํ๋ ์๋ ์๊ณ ์) ์ต์์ ๋ ๋ฒจ๋ก ๋ง๋ค์ด import ํ ๊ฒ์
๋๋ค. ์ ๋ ์ดํํธ๋ฅผ ์ต๋ํ ๋จ์ํ๊ฒ ๋ง๋ค๊ณ ์ถ๊ณ ๊ทธ ์์ ์ฝ๋ฐฑ์ ๋๋ ๊ฒ์ ๋จ์ํ๊ฒ ๋ง๋๋๋ฐ ๋ณ๋ก ๋์์ด ๋์ง ์์ต๋๋ค. (โ๋ง์ฝ์ ์ด๋ค props.onComplete
์ฝ๋ฐฑ์ด ์์ฒญ์ด ๋ณด๋ด์ง๊ณ ์์ ๋ ์คํ๋๋ค๋ฉด?โ) ํด๋์ค ์ปดํฌ๋ํธ์ ๋์์ ํ๋ด๋ผ์ ์์ง๋ง ๊ฒฝ์ ์ํ(race condition)๋ฅผ ํด๊ฒฐํ ์๋ ์์ต๋๋ค.
๊ฒฝ์ ์ํ์ ๋ํด
ํด๋์ค๋ก ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๋ ์ ํต์ ์ธ ์์ ๋ ์ด๋ ๊ฒ ์๊ฒผ์๊ฒ๋๋ค.
class Article extends Component {
state = {
article: null
};
componentDidMount() {
this.fetchData(this.props.id);
}
async fetchData(id) {
const article = await API.fetchArticle(id);
this.setState({ article });
}
// ...
}
์๋ง ์์๊ฒ ์ง๋ง, ์ด ์ฝ๋๋ ๋ฒ๊ทธ๊ฐ ์์ต๋๋ค. ์ปดํฌ๋ํธ๊ฐ ์ ๋ฐ์ดํธ๋๋ ์ํฉ์ ๋ค๋ฃจ์ง ์์ง์. ๊ทธ๋์ ๋ ๋ฒ์งธ ํด๋์ค ์ปดํฌ๋ํธ ์์ ๋ฅผ ์จ๋ผ์ธ์์ ์ฐพ์๋ณด๋ฉด ์ด๋ ๊ฒ ์๊ฒผ์ ๊ฒ๋๋ค.
class Article extends Component {
state = {
article: null
};
componentDidMount() {
this.fetchData(this.props.id);
}
componentDidUpdate(prevProps) { if (prevProps.id !== this.props.id) { this.fetchData(this.props.id); } } async fetchData(id) {
const article = await API.fetchArticle(id);
this.setState({ article });
}
// ...
}
์ด๊ฒ ํจ์ฌ ๋ซ์ฃ ! ํ์ง๋ง ์ฌ์ ํ ๋ฒ๊ทธ๊ฐ ์์ต๋๋ค. ๋ฒ๊ทธ๊ฐ ๋ฐ์ํ๋ ์ด์ ๋ ์์๋ฅผ ๋ณด์ฅํ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค. ๊ทธ๋์ ๋ง์ฝ ์ ๊ฐ {id: 10}
์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ๊ณ {id: 20}
์ผ๋ก ๋ฐ๊พธ์๋ค๋ฉด, {id: 20}
์ ์์ฒญ์ด ๋จผ์ ์์๋ฉ๋๋ค. ๊ทธ๋์ ๋จผ์ ์์๋ ์์ฒญ์ด ๋ ๋ฆ๊ฒ ๋๋์ ์๋ชป๋ ์ํ๋ฅผ ๋ฎ์ด์์ธ ์ ์์ต๋๋ค.
์ด๋ฅผ ๊ฒฝ์ ์ํ๋ผ๊ณ ํ๋ฉฐ, (๋ณดํต ๋น๋๊ธฐ ํธ์ถ์ ๊ฒฐ๊ณผ๊ฐ ๋์์ฌ ๋๊น์ง ๊ธฐ๋ค๋ฆฐ๋ค๊ณ ์ฌ๊ธฐ๋ฉฐ) ์์์ ์๋๋ก ๋ฐ์ดํฐ๊ฐ ํ๋ฅด๋ฉด์ async
/ await
์ด ์์ฌ์๋ ์ฝ๋์ ํํ ๋ํ๋ฉ๋๋ค. ์ฌ๊ธฐ์ ๋ฐ์ดํฐ๊ฐ ํ๋ฌ๊ฐ๋ค๋ ๋ง์ props๋ state๊ฐ async ํจ์ ์์์ ๋ฐ๋ ์ ์๋ค๋ ์ด์ผ๊ธฐ์
๋๋ค.
์ดํํธ๊ฐ ๋ง๋ฒ๊ฐ์ด ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด์ฃผ์ง ์์ต๋๋ค. ๊ฑฐ๊ธฐ๋ค async ํจ์๋ฅผ ์ดํํธ์ ์ง์ ์ ์ผ๋ก ์ ๋ฌํ๋ฉด ๊ฒฝ๊ณ ๊ฐ ๋ํ๋ ๊ฒ๋๋ค. (์ ํฌ ๋ฆฌ์กํธ ํ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ ์์ธ์ ๋ ์์ธํ๊ฒ ์ค๋ช ํ๋ ๊ฒฝ๊ณ ๋ฅผ ๋์์ฃผ์ด์ผ ํ ํ์๊ฐ ์์ต๋๋ค.)
์ฌ๋ฌ๋ถ์ด ์ฌ์ฉํ๋ ๋น๋๊ธฐ ์ ๊ทผ ๋ฐฉ์์ด ์ทจ์ ๊ธฐ๋ฅ์ ์ง์ํ๋ค๋ฉด ์์ฃผ ์ข์ต๋๋ค! ๊ทธ๋ฌ๋ฉด ํด๋ฆฐ์ ํจ์์์ ๋ฐ๋ก ๋น๋๊ธฐ ํจ์๋ฅผ ์ทจ์๋ฅผ ํ ์ ์์ต๋๋ค.
๋๋ ์ ์ผ ์ฝ๊ฒ ๋ถ๋ฆฐ(boolean) ๊ฐ์ผ๋ก ํ๋ฆ์ด ๋ฉ์ถฐ์ผ ํ๋ ํ์ด๋ฐ์ ์กฐ์ ํ ์ ์์ต๋๋ค.
function Article({ id }) {
const [article, setArticle] = useState(null);
useEffect(() => {
let didCancel = false; async function fetchData() {
const article = await API.fetchArticle(id);
if (!didCancel) {
setArticle(article); }
}
fetchData();
return () => {
didCancel = true; }; }, [id]);
// ...
}
์ด ๋งํฌ์ ๊ธ์ ์ด๋ป๊ฒ ์๋ฌ๋ฅผ ๋ค๋ฃจ๊ณ ์ํ๋ฅผ ๋ถ๋ฌ์ฌ์ง, ๋ํ ์ด๋ฐ ๋ก์ง์ ์ด๋ป๊ฒ ์ปค์คํ ํ ์ผ๋ก ์ถ์ํํ ์ ์๋์ง ์๊ฐํฉ๋๋ค. ํ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ํ์นญํ๋ ๋ฐฉ๋ฒ์ ๋ ์์ธํ ์๊ณ ์ถ๋ค๋ฉด ๊ผญ ์ฝ์ด๋ณด์ธ์.
์ง์ ์ฅ๋ฒฝ์ ๋ ๋์ด๊ธฐ
ํด๋์ค ์ปดํฌ๋ํธ์ ๋ผ์ดํ์ฌ์ดํด ๊ฐ๋ ์ผ๋ก ์๊ฐํ๋ฉด, ์ฌ์ด๋ ์ดํํธ๋ ๋๋๋ง ๊ฒฐ๊ณผ๋ฌผ๊ณผ ๋ค๋ฅด๊ฒ ๋์ํฉ๋๋ค. UI๋ฅผ ๋๋๋งํ๋ ๊ฒ์ props์ state๋ฅผ ํตํด ์ด๋ฃจ์ด์ง๋ฉฐ ์ด๋ค์ ์ผ๊ด์ฑ์ ๋ฐ๋ผ ๋ณด์ฅ๋ฐ์ต๋๋ค. ํ์ง๋ง ์ฌ์ด๋ ์ดํํธ๋ ์๋๋๋ค. ์ด๊ฒ ํํ ๋ฒ๊ทธ๊ฐ ์ผ์ด๋๋ ์์ธ์ ๋๋ค.
useEffect
์ ๊ฐ๋
์ผ๋ก ์๊ฐํ๋ฉด, ๋ชจ๋ ๊ฒ๋ค์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋๊ธฐํ๋ฉ๋๋ค. ์ฌ์ด๋ ์ดํํธ๋ ๋ฆฌ์กํธ์ ๋ฐ์ดํฐ ํ๋ฆ์ ์ผ๋ถ์
๋๋ค. ๋ชจ๋ useEffect
ํธ์ถ์์, ์ ๋๋ก๋ง ์ฝ๋๋ฅผ ์์ฑํ๋ค๋ฉด ์ฃ์ง ์ผ์ด์ค๋ฅผ ํจ์ฌ ์ฝ๊ฒ ๋ค๋ฃฐ ์ ์์ต๋๋ค.
ํ์ง๋ง ์ ๋๋ก useEffect
๋ฅผ ๋ค๋ฃจ๊ธฐ ์ํ ์ด๊ธฐ ๋น์ฉ์ ๋์ต๋๋ค. ์ง์ฆ์ด ๋ ์๋ ์์ต๋๋ค. ์ฃ์ง ์ผ์ด์ค๋ฅผ ์ ๋ค๋ฃจ๋ ๋๊ธฐํ ์ฝ๋๋ฅผ ์์ฑํ๋ ์ผ์ ๋๋๋ง๊ณผ ๋ณ๊ฐ๋ก ๋ฐ์ํ๋ ์ผํ์ฑ ์ฌ์ด๋ ์ดํํธ๋ฅผ ์คํํ๋ ๊ฒ ๋ณด๋ค ํ์ฐ์ ์ผ๋ก ์ด๋ ต์ต๋๋ค.
useEffect
๊ฐ ๋๋ถ๋ถ์ ์๊ฐ๊ณผ ํจ๊ป ํด์ผํ๋ ๋๊ตฌ ๋ผ๋ฉด ๊ฝค๋ ๊ฑฑ์ ์ค๋ฌ์ด ์ผ์ด ๋ฉ๋๋ค. ํ์ง๋ง useEffect
๋ ๋ฎ์ ์์ค์ ๋ ์ด์ด(๋ก์ฐ ๋ ๋ฒจ)์ ์์นํ ๊ตฌ์ฑ ์์์
๋๋ค. ์์ง ๋ชจ๋๊ฐ ํ
์ ๋ค๋ฃจ๊ธฐ ์์ํ์ง ์ผ๋ง ๋์ง ์์ ์๊ธฐ๋ผ์ ํญ์ ๋ก์ฐ ๋ ๋ฒจ API๋ฅผ ๋ค๋ฃจ๊ณ ์์ต๋๋ค. ํนํ ํํ ๋ฆฌ์ผ์์์. ํ์ง๋ง ์ค์ ๋ก ์ปค๋ฎค๋ํฐ๋ ๋ ๋์ ์์ค์ผ๋ก ์ถ์ํ๋ ํ
์ผ๋ก ์ฎ๊ฒจ๊ฐ ๊ฒ์
๋๋ค.
์ ๋ ์๋ก ๋ค๋ฅธ ์ฑ์ด ์์ ๋ง์ useFetch
ํ
์ ๋ง๋ค์ด ์ธ์ฆ ๋ก์ง์ ์บก์ํํ๊ฑฐ๋, useTheme
๋ฅผ ์ฌ์ฉํ์ฌ ํ
๋ง ์ปจํ
์คํธ๋ฅผ ์ฌ์ฉํ๋ ๋ชจ์ต์ ๋ณด์์ต๋๋ค. ์ด๋ฐ ๋๊ตฌ ๋ชจ์์ ๊ฐ์ง๊ฒ ๋๋ฉด, useEffect
๋ฅผ ์ง์ ์ธ ์ผ์ ๊ทธ๋ฆฌ ๋ง์ง ์์ ๊ฒ์
๋๋ค. ํ์ง๋ง ๊ทธ ์ ์ฐํจ์ ๋ชจ๋ ํ
์ ๋ง๋๋๋ฐ ์ถฉ๋ถํ ์ ์ฉํ๊ฒ ์์ฉํ ์ ์์ต๋๋ค.
์์ง๊น์ง๋ useEffect
๊ฐ ๊ฐ์ฅ ํํ ์ฌ์ฉ๋๋ ๊ฒฝ์ฐ๋ ๋ฐ์ดํฐ ํ์นญ์
๋๋ค. ํ์ง๋ง ๋ฐ์ดํฐ ํ์นญ์ ์๋ฐํ ๋งํด ๋๊ธฐํ์ ๋ฌธ์ ๋ ์๋๋๋ค. ํนํ๋ ๋ช
๋ฐฑํ ๊ฒ์ด ์ฃผ๋ก ์ด๋ด ๋๋ deps๊ฐ []
๊ฐ ๋๊ธฐ ๋๋ฌธ์ด์ฃ . ๋๋์ฒด ์ฐ๋ฆฌ๋ ๋ฌด์์ ๋๊ธฐํํ๊ณ ์์๊น์?
์ฅ๊ธฐ์ ์ธ ๊ด์ ์์ ๋ฐ์ดํฐ ๋ถ๋ฌ์ค๋ ๋ก์ง์ ํด๊ฒฐํ๊ธฐ ์ํด Suspense๊ฐ ๋์ ๋๋ฉด ์๋ ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ด ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฆฌ์กํธ์๊ฒ ์ด๋ค ๋น๋๊ธฐ์ ์ธ ํ์(์ฝ๋, ๋ฐ์ดํฐ, ์ด๋ฏธ์ง ๋ฑ ๋ชจ๋ ๊ฒ)๊ฐ ์ค๋น๋ ๋๊น์ง ๋๋๋ง์ ์ ์ ๋ฏธ๋ฃฐ ์ ์๋๋ก ์ง์ํ๊ฒ ๋ ๊ฒ์ ๋๋ค.
Suspense๊ฐ ์์ฐ์ค๋ฝ๊ฒ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๋ ๊ฒฝ์ฐ๋ฅผ ๋ ๋ง์ด ์ปค๋ฒํ๊ฒ ๋๋ฉด, ์์ธก์ปจ๋ useEffect
๋ ๋์ฑ ๋ก์ฐ ๋ ๋ฒจ๋ก ๋ด๋ ค๊ฐ ํ์์ ์ ๋ค์ด ์ง์ ์ผ๋ก ์ฌ์ด๋ ์ดํํธ๋ฅผ ํตํด props์ state๋ฅผ ๋๊ธฐํํ๊ณ ์ ํ ํ์๊ฐ ์์ ๋ ์ฌ์ฉํ๋ ๋๊ตฌ๊ฐ ๋ ๊ฒ์
๋๋ค. ๋ฐ์ดํฐ ํ์นญ๊ณผ ๋ค๋ฅด๊ฒ ์๋ ๋์์ธ ๋ ๋๋ก ์ด๋ฐ ๋๊ธฐํ ์ผ์ด์ค๋ฅผ ์์ฐ์ค๋ฝ๊ฒ ๋ค๋ฃน๋๋ค. ํ์ง๋ง ๊ทธ ๋๊น์ง๋, ์ฌ๊ธฐ ์๋ ๊ฒ๊ณผ ๊ฐ์ ์ปค์คํ
ํ
์ด ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ๋ฐ์ดํฐ ํ์นญ ๋ก์ง์ ๋ค๋ฃจ๋ ์ข์ ๋ฐฉ๋ฒ์
๋๋ค.
๋ง์น๋ฉฐ
์ด์ ์ฌ๋ฌ๋ถ์ ์ ๊ฐ ์๊ณ ์๋ ์ดํํธ์ ๋ํ ์ ๋ณด ๊ฑฐ์ ์ ๋ถ๋ฅผ ์๊ฒ ๋์์ต๋๋ค, ๋ค์ ์์ ๋ถ๋ถ์ผ๋ก ๋์๊ฐ ์์ฝ๋ณธ์ ์ฝ์ด ๋ณด์ธ์. ์ดํด๊ฐ ๋์๋์? ์๋๋ฉด ์ ๊ฐ ๋ญ ๋น ๋จ๋ ธ์๊น์? (์์ง ์ ๋์ ์ํฌ๊ฐ ๋ง๋ฅด์ง ์์์ด์!)
ํธ์ํฐ์์ ์๊ฒฌ์ ์ฃผ์๋ฉด ์ข๊ฒ ์ต๋๋ค! ์ฝ์ด์ฃผ์ ์ ๊ณ ๋ง์ต๋๋ค.