-
[React] Effect HookcodeStates front-end/React 2023. 2. 2. 17:46๋ฐ์ํ
๐Effect Hook
React ์ปดํฌ๋ํธ ์ธ๋ถ์์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๊ณ ๋ฐ์์ค๋ ๊ณผ์
๐Side Effect (๋ถ์ ํจ๊ณผ)
React์์ ์ปดํฌ๋ํ ๋ด์์ fetch๋ฅผ ์ฌ์ฉํด API ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๊ฑฐ๋ ์ด๋ฒคํธ๋ฅผ ํ์ฉํด
DOM ์ง์ ์กฐ์ํ ๋ Side Effect๊ฐ ๋ฐ์ํ๋ค๊ณ ํ๋ค.
-------------------------------
๐ก fetch๊ฐ ๋ญ์์? ์๋ฒ์ ๋คํธ์ํฌ ์์ฒญ์ ๋ณด๋ด๊ณ ์๋ก์ด ์ ๋ณด๋ฅผ ๋ฐ์์ค๋ ์ผ
// fetch() ๊ธฐ๋ณธ ๋ฌธ๋ฒ let promise = fetch(url, [options]) //fetch ํจ์๋ API๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐฑ์๋ ์๋ฒ์ ๋น๋๊ธฐ ์์ฒญ์ ํ๋ ๋ฐฉ์ ์ค ํ๋ //fetch API๋ 3๊ฐ์ interfeace๋ฅผ ๋์ ํ๊ณ ์๋๋ฐ Headers, Request, Response์ด๋ค. //url-์ ๊ทผํ๊ณ ์ ํ๋ URL //options - ์ ํ ๋งค๊ฐ๋ณ์, mehtod๋ header ๋ฑ์ ์ง์ ํ ์ ์๋ค. fetch('url') .then(response => response.json()) .then(response => data.filter(item => item.isRequired));
-------------------------------
// ์ ์ญ ๋ณ์ foo๋ฅผ ์์ ํ๋ ์์ let foo = 'hello'; function bar() { foo = 'world'; } bar(); // bar๋ Side Effect๋ฅผ ๋ฐ์์ํต๋๋ค!
๐Pure Function(์์ ํจ์)
์ค์ง ํจ์์ ์ ๋ ฅ๋ง์ด ํจ์์ ๊ฒฐ๊ณผ์ ์ํฅ์ ์ฃผ๋ ํจ์๋ฅผ ์๋ฏธ
์์ํจ์ ์กฐ๊ฑด
ํจ์์ ์ ๋ ฅ์ด ์๋ ๋ค๋ฅธ ๊ฐ์ด ํจ์์ ๊ฒฐ๊ณผ์ ์ํฅ์ ๋ฏธ์น๋ ๊ฒฝ์ฐ, ์์ ํจ์ x
์ ๋ ฅ์ผ๋ก ์ ๋ฌ๋ ๊ฐ์ ์์ x
์์ ํจ์์๋ ๋คํธ์ํฌ ์์ฒญ๊ณผ ๊ฐ์ Side Effect x
์ด๋ ํ ์ ๋ฌ์ธ์๊ฐ ์ฃผ์ด์ง ๊ฒฝ์ฐ, ํญ์ ๋๊ฐ์ ๊ฐ์ด ๋ฆฌํด๋จ์ ๋ณด์ฅ
function upper(str) { return str.toUpperCase(); // toUpperCase ๋ฉ์๋๋ ์๋ณธ์ ์์ ํ์ง ์์ต๋๋ค (Immutable) } upper('hello') // 'HELLO'
๐ก
- Math.random()์ ์์ ํจ์๊ฐ ์๋๋๋ค. ์์ผ๊น์?
- ์ด๋ค ํจ์๊ฐ fetch API๋ฅผ ์ด์ฉํด AJAX ์์ฒญ์ ํ๋ค๊ณ ๊ฐ์ ํด ๋ด ์๋ค. ์ด ํจ์๋ ์์ ํจ์๊ฐ ์๋๋๋ค. ์์ผ๊น์?
๐
- random ๊ฐ์ ๋ง๊ทธ๋๋ก ๊ฐ์ด ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ์์ํจ์๊ฐ ๋ ์ ์๋ค
- ๋คํธ์ํฌ ์ํฉ, ์๋ฒ์ํ์ ๋ฐ๋ผ ์๋ต์ฝ๋๊ฐ ๋ฌ๋ผ์ง๊ธฐ ๋๋ฌธ์ ์์ธก ๋ถ๊ฐ๋ฅ
๐๐ผ๐๐ผ AJAX์์ฒญ์ด ํ์ํ๊ฑฐ๋, localStorage ๋๋ ํ์ด๋จธ๊ฐ์ react์๋ ์๊ด์๋ API๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๋ฐ์
React ์ ์ฅ์์๋ ์ ๋ถ Side Effect ์ด๊ฒ์ ๋ค๋ฅด๊ธฐ ์ํด Effect Hook์ ์ ๊ณต
๐Effect Hook - useEffect
useEffect๋ ์ปดํฌ๋ํธ ๋ด์์ Side effect(ํน์ ์์ )๋ฅผ ์คํํ ์ ์๊ฒ ํ๋ Hook
์ด ์ปดํฌ๋ํธ์์ ์คํํ๋ Side effect๋ ๋ธ๋ผ์ฐ์ API๋ฅผ ์ด์ฉํ์ฌ, ํ์ดํ์ ๋ณ๊ฒฝํ๋ ๊ฒ
API
useEffect์ ์ฒซ ๋ฒ์งธ ์ธ์๋ ํจ์
ํด๋น ํจ์ ๋ด์์ side effect๋ฅผ ์คํํ๋ฉด ๋๋ค.
์๋กญ๊ฒ ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง ๋ ๋ Effect Hook์ด ์คํ
- ์ปดํฌ๋ํธ ์์ฑ ํ ์ฒ์ ํ๋ฉด์ ๋ ๋๋ง(ํ์)
- ์ปดํฌ๋ํธ์ ์๋ก์ด props๊ฐ ์ ๋ฌ๋๋ฉฐ ๋ ๋๋ง
- ์ปดํฌ๋ํธ์ ์ํ(state)๊ฐ ๋ฐ๋๋ฉฐ ๋ ๋๋ง
Hook์ ์ธ ๋ ์ฃผ์ํ ์
- ์ต์์์์๋ง Hook์ ํธ์ถํ๋ค.
- ๋ฆฌ์กํธ ํจ์ ๋ด์์ Hook์ ํธ์ถํ๋ค.
๐์กฐ๊ฑด๋ถ effect ๋ฐ์(dependency array)
useEffect์ ๋ ๋ฒ์งธ ์ธ์๋ ๋ฐฐ์ด
์กฐ๊ฑด์ boolean ํํ์ ํํ์์ด ์๋, ์ด๋ค ๊ฐ์ ๋ณ๊ฒฝ์ด ์ผ์ด๋ ๋๋ฅผ ์๋ฏธ
๋ฐ๋ผ์ ํด๋น ๋ฐฐ์ด์ ์ด๋ค ๊ฐ์ ๋ชฉ๋ก์ด ๋ค์ด๊ฐ๋ค(์ข ์์ฑ ๋ฐฐ์ด)
API
useEffect(ํจ์, [์ข ์์ฑ1, ์ข ์์ฑ2, ...])
useEffect์ ๋ ๋ฒ์งธ ์ธ์๋ ์ข ์์ฑ ๋ฐฐ์ด
๋ฐฐ์ด ๋ด์ ์ข ์์ฑ1, ๋๋ ์ข ์์ฑ2์ ๊ฐ์ด ๋ณํ ๋, ์ฒซ ๋ฒ์งธ ์ธ์์ ํจ์๊ฐ ์คํ
๐๋จ ํ๋ฒ๋ง ์คํ๋๋ Effect ํจ์
- ๋น ๋ฐฐ์ด ๋ฃ๊ธฐ : ๋น ๋ฐฐ์ด์ useEffect์ ๋ ๋ฒ์งธ ์ธ์๋ก ์ฌ์ฉํ๋ฉด, ์ด๋์๋ ์ปดํฌ๋ํธ๊ฐ ์ฒ์ ์์ฑ๋ ๋๋ง effect ํจ์๊ฐ ์คํ๋๋ค. ๋ํ์ ์ผ๋ก ์ฒ์ ๋จ ํ ๋ฒ, ์ธ๋ถ API๋ฅผ ํตํด ๋ฆฌ์์ค๋ฅผ ๋ฐ์์ค๊ณ ๋ ์ด์ API ํธ์ถ์ด ํ์ํ์ง ์์ ๋์ ์ฌ์ฉํ ์ ์๋ค.
- useEffect(ํจ์, [])
- ์๋ฌด๊ฒ๋ ๋ฃ์ง ์๊ธฐ : ๊ธฐ๋ณธ ํํ์ useEffect๋ ์ปดํฌ๋ํธ๊ฐ ์ฒ์ ์์ฑ๋๊ฑฐ๋, props๊ฐ ์
๋ฐ์ดํธ๋๊ฑฐ๋, ์ํ(state)๊ฐ ์
๋ฐ์ดํธ๋ ๋ effect ํจ์๊ฐ ์คํ๋๋ค.
- useEffect(ํจ์)
๐Data Fetching : ํํฐ๋ง ์์ ๋ค์ ๋ณด๊ธฐ
๋ชฉ๋ก ๋ด ํํฐ๋ง์ ๊ตฌํํ๊ธฐ ์ํด์๋ ๋ค์๊ณผ ๊ฐ์ ๋ ๊ฐ์ง ์ ๊ทผ์ด ์์ ์ ์๋ค
- ์ปดํฌ๋ํธ ๋ด์์ ํํฐ๋ง: ์ ์ฒด ๋ชฉ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๊ณ , ๋ชฉ๋ก์ ๊ฒ์์ด๋ก filter ํ๋ ๋ฐฉ๋ฒ
- ์ปดํฌ๋ํธ ์ธ๋ถ์์ ํํฐ๋ง: ์ปดํฌ๋ํธ ์ธ๋ถ๋ก API ์์ฒญ์ ํ ๋, ํํฐ๋ง ํ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์์ค๋ ๋ฐฉ๋ฒ (๋ณดํต, ์๋ฒ์ ๋งค๋ฒ ๊ฒ์์ด์ ํจ๊ป ์์ฒญํ๋ ๊ฒฝ์ฐ๊ฐ ์ด์ ํด๋น)
์ฅ๋จ์
์ฅ์ ๋จ์ ์ปดํฌ๋ํธ ๋ด๋ถ์์ ์ฒ๋ฆฌ HTTP ์์ฒญ์ ๋น๋๋ฅผ ์ค์ผ ์ ์๋ค ๋ธ๋ผ์ฐ์ (ํด๋ผ์ด์ธํธ)์ ๋ฉ๋ชจ๋ฆฌ ์์ ๋ง์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ๊ฒ ๋๋ฏ๋ก, ํด๋ผ์ด์ธํธ์ ๋ถ๋ด์ด ๋์ด๋๋ค ์ปดํฌ๋ํธ ์ธ๋ถ์์ ์ฒ๋ฆฌ ํด๋ผ์ด์ธํธ๊ฐ ํํฐ๋ง ๊ตฌํ์ ์๊ฐํ์ง ์์๋ ๋๋ค ๋น๋ฒํ HTTP ์์ฒญ์ด ์ผ์ด๋๊ฒ ๋๋ฉฐ, ์๋ฒ๊ฐ ํํฐ๋ง์ ์ฒ๋ฆฌํ๋ฏ๋ก ์๋ฒ๊ฐ ๋ถ๋ด์ ๊ฐ์ ธ๊ฐ๋ค ๐AJAX ์์ฒญ
useEffect(() => { fetch(`http://์๋ฒ์ฃผ์/proverbs?q=${filter}`) .then(resp => resp.json()) .then(result => { setProverbs(result); }); }, [filter]);
๐AJAX ์์ฒญ์ด ๋งค์ฐ ๋๋ฆด ๊ฒฝ์ฐ?
๋ชจ๋ ๋คํธ์ํฌ ์์ฒญ์ด ํญ์ ์ฆ๊ฐ์ ์ธ ์๋ต์ ๊ฐ์ ธ๋ค์ฃผ๋ ๊ฒ์ ์๋๋ค.
์ธ๋ถ API ์ ์์ด ๋๋ฆด ๊ฒฝ์ฐ๋ฅผ ๊ณ ๋ คํ์ฌ, ๋ก๋ฉ ํ๋ฉด(loading indicator)์ ๊ตฌํ์ ํ์์
loading indicator
const [isLoading, setIsLoading] = useState(true); // ์๋ต, LoadingIndicator ์ปดํฌ๋ํธ๋ ๋ณ๋๋ก ๊ตฌํํ์์ ๊ฐ์ ํฉ๋๋ค return {isLoading ? <LoadingIndicator /> : <div>๋ก๋ฉ ์๋ฃ ํ๋ฉด</div>}
fetch ์์ฒญ์ ์ ํ๋ก setIsLoading์ ์ค์ ํด ์ฃผ์ด ๋ณด๋ค ๋์ UX๋ฅผ ๊ตฌํํ ์ ์๋ค.
useEffect(() => { setIsLoading(true); fetch(`http://์๋ฒ์ฃผ์/proverbs?q=${filter}`) .then(resp => resp.json()) .then(result => { setProverbs(result); setIsLoading(false); }); }, [filter]);
๋ฐ์ํ'codeStates front-end > React' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[React] UI/UX (0) 2023.02.15 [React] ์ค์ต - StatesAirline Client (0) 2023.02.04 [React] ๋ฐ์ดํฐ ํ๋ฆ (0) 2023.02.02 [React] ์ค์ต - React Twittler State & Props (0) 2023.01.30 [React] ์ด๋ฒคํธ ์ฒ๋ฆฌ & Controlled Component & React ๋ฐ์ดํฐ ํ๋ฆ (0) 2023.01.26