2024-03-12.md
๐กDIL: ๋ชจ๋ ๋ฆฌ์กํธ ๋ฅ ๋ค์ด๋ธ, 2์ฃผ์ฐจ-2
์คํฐ๋: ์๊ฐ CS, https://github.com/monthly-cs/2024-03-modern-react-deep-dive
์ค๋ ์งํ: ๊ฐ์ธ๊ณต๋ถ
DIL-week2-2_2024-03-12
| DIL ์ฃผ์ฐจ | ๋ฒ์ | ๋ด์ฉ | ์ค๋์ฐจ ์ง๋ | | -------- | ------ | ------------------------------ | ----------- | | 2์ฃผ์ฐจ | 3, 5์ฅ | ๋ฆฌ์กํธ ํ ๊ณผ ์ํ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ | 194p~207p |
์ค๋ ์ฝ์ ๋ด์ฉ์ markdown์ผ๋ก ๊ฐ๋จํ ๋ฉ๋ชจ
์ฝ์ ์๊ฐ: 11์~12์
๊ฐ๊ธฐ ์ด์๐ค
React Hook ํํค์น๊ธฐ
useState
๊ฒ์ผ๋ฅธ ์ด๊ธฐํ๋? lazy initialization
- useState์ ์ด๊น๊ฐ์ด ๋ณต์กํ๊ฑฐ๋ ๋ฌด๊ฑฐ์ด ์ฐ์ฐ์ ํฌํจํ๊ณ ์์ ๋ ์ฌ์ฉ
- ๊ฒ์ผ๋ฅธ ์ด๊ธฐํ ํจ์๋ state๊ฐ ์ฒ์ ๋ง๋ค์ด์ง ๋๋ง ์ฌ์ฉ๋๋ค(์ดํ ํจ์์ ์คํ์ ๋ฌด์๋๋ค)
- ์ถ์ฒ ์ผ์ด์ค (์คํ ๋น์ฉ์ด ๋ง์ด ๋๋ ๊ฒฝ์ฐ)
- localStorage, sessionStorage ์ ๊ทผ
- ๋ฐฐ์ด ์ ๊ทผ: map, filter, find
- ์ด๊ธฐ๊ฐ ๊ฒ์ฐ์ ํจ์ ํธ์ถ์ด ํ์ํ ๋
useEffect
- ์ ํ๋ฆฌ์ผ์ด์ ๋ด ์ปดํฌ๋ํธ์ ๊ฐ๋ค์ ํ์ฉํ์ฌ ๋๊ธฐ์ ์ผ๋ก ๋ถ์ ํจ๊ณผ๋ฅผ ๋ง๋ ๋ค. side-effects
- ์ด๋ป๊ฒ ์์กด์ฑ ๋ฐฐ์ด์ด ๋ณ๊ฒฝ๋ ๊ฒ์ ์ ์ ์๋?
- ํจ์ ์ปดํฌ๋ํธ๋ => ๋งค๋ฒ ํจ์๋ฅผ ์คํํด ๋๋๋ง์ ์ํํ๋ค
- ๋๋๋ง ์๋ง๋ค ๊ณ ์ ์ state, props ๊ฐ์ ๊ฐ๊ณ ์์
- useEffect๋? ํ๋ฒํ ํจ์๋ค
- ํน๋ณํ ๊ธฐ๋ฅ์ ๊ฐ์ง ๊ฒ์ด ์๋ like proxy, ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ, ์ต์ ๋ฒ
- state๊ณผ props ๋ณํ > ๋๋๋ง > ๋ถ์ ํจ๊ณผ
ํด๋ฆฐ์ ํจ์ clean-up function
- ํด๋ฆฐ์
ํจ์๋? => ์ด์ state์ ์ฐธ์กฐํด ์คํ๋๋ค
- (์๊ธฐ) ํด๋ฆฐ์ ํจ์๋ ์๋ก์ด ๊ฐ๊ณผ ํจ๊ป ๋๋๋ง๋ ๋ค์ ์คํ๋๋ค
- (๊ฐ) ํด๋ฆฐ์ ํจ์๋ ์๋ก์ด ๊ฐ์ ์ฝ๋ ๊ฒ์ด ์๋๋ผ, ํจ์๊ฐ ์ ์๋์ ๋น์์ ์ ์ธ๋๋ ์ด์ ๊ฐ์ ๋ณด๊ณ ์คํ๋๋ค
- useEffect๋ ์ฝ๋ฐฑ์ด ์คํ๋ ๋ => ํด๋ฆฐ์
ํจ์๊ฐ ์กด์ฌํ๋ค๋ฉด ํด๋ฆฐ์
ํจ์๋ฅผ ์คํํ ํ ์ฝ๋ฐฑ์ ์คํ
- unmount๊ฐ ์๋!
- ํจ์ ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋๋๋ง ๋์ ๋, ์์กด์ฑ ๋ณํ๊ฐ ์์์ ๋น์ ์ด์ ์ ๊ฐ์ ๊ธฐ์ค์ผ๋ก ์คํ๋๋ => ์ฒญ์ ๊ฐ๋ ~!
์์กด์ฑ ๋ฐฐ์ด
- useEffect๋ ์์กด์ฑ ๋ฐฐ์ด์ ์ด์ ๊ฐ๊ณผ ํ์ฌ ๊ฐ์ ์์ ๋น๊ตํ๋ค.(Object.is)
- ํ๋๋ผ๋ ๋ณ๊ฒฝ ์ฌํญ์ด ์๋ค๋ฉด, callback์ผ๋ก ์ ์ธํ ๋ถ์ ํจ๊ณผ๋ฅผ ์คํํ๋ค.
์์กด์ฑ ๋ฐฐ์ด ์์ฒด๊ฐ ์๋ ๊ฒฝ์ฐ
- ์ปดํฌ๋ํธ๊ฐ ๋๋๋ง ๋๋์ง ํ์ธ์ฉ
- ๊ทธ๋ฅ useEffect ์์ด ์ฐ๋ฉด ๋๋ ๊ฑฐ ์๋?
-
์๋ฒ ์ฌ์ด๋ ๋๋๋ง ๊ด์
- ํด๋ผ์ด์ธํธ ์ฌ์ด๋์์ ์คํ๋๋ ๊ฒ์ ๋ณด์ฅํ๋ค
- ์ฆ, window ๊ฐ์ฒด์ ์ ๊ทผ์ ์์กดํ๋ ์ฝ๋ ok
-
useEffect๋ ์ปดํฌ๋ํธ ๋๋๋ง(side effect)์ด ์๋ฃ๋ ์ดํ์ ์คํ๋๋ค
- ์ฝ๋๋ฅผ ์ง์ ์คํํ ์, ๋๋๋ง ๋์ค์ ์คํ๋๋ค
- (์๋ฒ ์ฌ์ด๋ ๋๋๋ง์ ๊ฒฝ์ฐ, ์๋ฒ์์ ์คํ)
- ํจ์ ์ปดํฌ๋ํธ์ ๋ฐํ์ ์ง์ฐ์ํจ๋ค. ๋ฌด๊ฑฐ์ด ์์ ์ผ ๊ฒฝ์ฐ ๋๋๋ง์ ๋ฐฉํด, ์ฑ๋ฅ ์ ํ
์ฃผ์ํ ์ : ์์กด์ฑ ๋ฐฐ์ด์ ๋น ๋ฐฐ์ด์ ๊ณ ์งํ๋ฉด ์๋๋ ์ด์
eslint-disable-line react-hook/exhaustive-deps
- ์ ๊ทผ๋ฒ์ ๋ฌธ์
- ์ปดํฌ๋ํธ๋ฅผ ๋ง์ดํธ ํ๋ ์์ ์๋ง ์คํํ๊ณ ์ถ๋ค?
- componentDidMount์ ๊ธฐ๋ฐํ ์ ๊ทผ๋ฒ์ผ๋ก, ์ฌ์ฉํด์ ์๋จ
- side effect
- ์ปดํฌ๋ํธ์ state, props์ ๊ฐ ๋ณ๊ฒฝ๊ณผ, ๋ถ์ ํจ๊ณผ ์ฌ์ด์ ์ฐ๊ฒฐ ๊ณ ๋ฆฌ๊ฐ ๋์ด์ง
- ๋ถ์ ํจ๊ณผ๊ฐ ์ค์ ๋ก ๊ด์ฐฐ๋์ ์คํ๋์ผ ํ๋ ๊ฐ๊ณผ ๋ณ๊ฐ๋ก ์๋๋จ
- ๋ถ์ ํจ๊ณผ๊ฐ ๋ถ์ ํจ๊ณผ๊ฐ ์๋๊ฒ ๋๋ ๊ฒ
- ์ปดํฌ๋ํธ์ state, props์ ๊ฐ ๋ณ๊ฒฝ๊ณผ, ๋ถ์ ํจ๊ณผ ์ฌ์ด์ ์ฐ๊ฒฐ ๊ณ ๋ฆฌ๊ฐ ๋์ด์ง
- ๋ก์ง์ ๋ฌธ์ ์ฒดํฌ
- ์ ๋ง ๋ถ์ ํจ๊ณผ๊ฐ ์ปดํฌ๋ํธ์ ์ํ์ "๋ณ๊ฐ"๋ก ์๋ํด์ผ๋ง ํ๋ ์ง ํ์ธ
- ๋ถ์ ํจ๊ณผ์ ์คํ ์์น๊ฐ ์ ์ ํ ์ง ํ์ธ
- ํ์ํ๋ค๋ฉด, ๋ถ๋ชจ ์ปดํฌ๋ํธ์์ ๋ณ๊ฒฝ๋ ๊ฐ์ props๋ก ์ ๋ฌ๋ฐ๊ธฐ
๋ถ์ ํจ๊ณผ์ ํ๋ฆ
์ ๊ฑฐ์ค๋ฅด์ง ์์ ์ ์๋ค.
useEffect ์ฒซ ๋ฒ์งธ ์ธ์(์ฝ๋ฐฑ ํจ์)์ ํจ์๋ช ๋ถ์ฌํ๊ธฐ
- ํด๋น useEffect์ ๋ชฉ์ ์ ํ์
ํ๊ธฐ ์ํด ์ ์ฉํ๊ฒ ์ฌ์ฉํ ์ ์๋ค.
- ์ฑ ์์ ์ต์ํ์ผ๋ก ์ขํ๋ค
useEffect(
function logActiveUse() {
logging(user.id);
},
[user.id]
);
๊ฑฐ๋ํ useEffect X
- ๋ถ์ ํจ๊ณผ๊ฐ ํฌ๋ค๋ฉด?
- ๋๋๋ง์๋ ์ํฅ์ ์ ๊ฒ ๋ฏธ์น๋ค (๋๋๋ง ์ดํ์ ์คํ๋๋๊น)
- ์๋ฐ์คํฌ๋ฆฝํธ ์คํ ์ฑ๋ฅ์ ์ํฅ์ ๋ฏธ์น๋ค (๋๋๋ง ์ ์์กด์ฑ ๋ฐฐ์ด์ด ๋ณ๊ฒฝ๋์์ ๋๋ง๋ค ์คํ๋๋๊น)
- ๊ด๋ฆฌํ๊ธฐ ์ด๋ ค์ด ์์ค๊น์ง ์ปค์ง๋ค๋ฉด?
- ์ธ์ ๋ฐ์ํ๋ ์ง ์ ์ ์์
- ์ต๋ํ useCallback๊ณผ useMemo๋ก ์ ์ ํ ๋ด์ฉ๋ง useEffect์ ๋ด๋๋ค.
๋ถํ์ํ ์ธ๋ถ ํจ์ x
- useEffect ๋ฐ์์ ํจ์๋ฅผ ์ ์ธํ๋ฉด?
- ๋ถํ์ํ ์ฝ๋๊ฐ ๋ง์์ง๊ณ , ๊ฐ๋ ์ฑ์ด ๋จ์ด์ง
- useEffect ๋ด์์ ์ฌ์ฉํ side effect๋ผ๋ฉด? => ๋ด๋ถ์์ ๋ง๋ค์ด์ ์ ์ํด์ ์ฌ์ฉ
์ useEffect์ ์ฝ๋ฐฑ ์ธ์๋ ๋น๋๊ธฐ๊ฐ ๋ ์ ์๋๊ฐ?
"๊ฐ๋ฐ์์ ํธ์"
race condition of useEffect
- ๋น๋๊ธฐ ํจ์์ ์๋ต ์๋์ ๋ฐ๋ผ ๊ฒฐ๊ณผ๊ฐ ์ด์ํ ์ ์๋ค
- ์ํ๋ณํA: ๋น๋๊ธฐ ์ฒ๋ฆฌ์ 10์ด
- ์ดํ ์ํ๋ณํB: ๋น๋๊ธฐ ์ฒ๋ฆฌ์ 1์ด
- race condition์ด ๋ฐ์ํด state์ด => B => A๊ฐ ๋ ์ ์๋ค
- ๋น๋๊ธฐ ํจ์์ ์๋ต ์๋์ ๋ฐ๋ผ ๊ฒฐ๊ณผ๊ฐ ์ด์ํ ์ ์๋ค
- cleanup ํจ์์ ์คํ ์์๋ฅผ ๋ณด์ฅํ ์ ์๋ค.
์์ - 207p
- useEffect ๋ด๋ถ์ async Function ์ ์ธ, ํน์ ๋น๋๊ธฐ IIFE
- ํด๋ฆฐ์ ํจ์์ ๋น๋๊ธฐ ์ฒ๋ฆฌ, Fetch์ ๊ฒฝ์ฐ abortController๋ก ์์ฒญ ์ทจ์
function Component({ id }: { id: string }) {
const [info, setInfo] = useState<number | null>(null);
useEffect(() => {
const controller = new AbortController();
(async () => {
const result = await fetchInfo(id, { signal: controller.signal });
setInfo(await result.json());
})();
return () => controller.abort();
}, [id]);
return <></>;
}