Post

๐Ÿช React Hook ๊ฐœ๋… ์ •๋ฆฌ

๐Ÿช React Hook ๊ฐœ๋… ์ •๋ฆฌ

1. Hook์ด๋ž€?

Hook(ํ›…)์€ React์˜ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ(function component)์—์„œ
๊ธฐ์กด ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์—์„œ๋งŒ ๊ฐ€๋Šฅํ–ˆ๋˜ ๊ธฐ๋Šฅ(์ƒํƒœ ๊ด€๋ฆฌ, ์ƒ๋ช…์ฃผ๊ธฐ ๊ด€๋ฆฌ ๋“ฑ)์„
์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ํŠน๋ณ„ํ•œ ํ•จ์ˆ˜์ด๋‹ค.

React 16.8 ๋ฒ„์ „๋ถ€ํ„ฐ ๋„์ž…๋˜์—ˆ์œผ๋ฉฐ,
์ปดํฌ๋„ŒํŠธ๋ฅผ ๋” ๊ฐ„๊ฒฐํ•˜๊ณ  ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ค์–ด ์ค€๋‹ค.


2. ์™œ Hook์ด ์ƒ๊ฒผ์„๊นŒ?

๊ธฐ์กด ๋ฌธ์ œ์ 

  • ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ๋Š” ๋ฌธ๋ฒ•์ด ๋ณต์žกํ•˜๊ณ  this ๋ฐ”์ธ๋”ฉ์ด ํ•„์š”ํ–ˆ๋‹ค.
  • ์—ฌ๋Ÿฌ ์ƒ๋ช…์ฃผ๊ธฐ ๋ฉ”์„œ๋“œ(componentDidMount, componentDidUpdate, componentWillUnmount)์—์„œ
    ํ•˜๋‚˜์˜ ๋กœ์ง์„ ๋‚˜๋ˆ  ์ž‘์„ฑํ•ด์•ผ ํ•ด์„œ ๊ด€๋ฆฌ๊ฐ€ ์–ด๋ ค์› ๋‹ค.
  • ์ƒํƒœ ๊ด€๋ จ ๋กœ์ง์„ ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ ๊ฐ„์— ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์–ด๋ ค์› ๋‹ค.

Hook์˜ ๋“ฑ์žฅ์œผ๋กœ ํ•ด๊ฒฐ๋œ ์ 

  • ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ๋„ ์ƒํƒœ(state)์™€ ์ƒ๋ช…์ฃผ๊ธฐ ๋กœ์ง์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ปค์Šคํ…€ ํ›…(Custom Hook)์„ ํ†ตํ•ด ๋กœ์ง์„ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•˜๊ณ  ํ…Œ์ŠคํŠธ๊ฐ€ ์‰ฌ์›Œ์กŒ๋‹ค.

3. ๊ธฐ๋ณธ ๊ทœ์น™ (Rules of Hooks)

  1. ๋ฐ˜๋“œ์‹œ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์˜ ์ตœ์ƒ์œ„์—์„œ๋งŒ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค.
    โ†’ ๋ฐ˜๋ณต๋ฌธ, ์กฐ๊ฑด๋ฌธ, ์ค‘์ฒฉ ํ•จ์ˆ˜ ์•ˆ์—์„œ๋Š” ์‚ฌ์šฉ ๋ถˆ๊ฐ€.

  2. React ํ•จ์ˆ˜(์ปดํฌ๋„ŒํŠธ or ์ปค์Šคํ…€ ํ›…) ์•ˆ์—์„œ๋งŒ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค.
    โ†’ ์ผ๋ฐ˜ JavaScript ํ•จ์ˆ˜์—์„œ๋Š” ํ˜ธ์ถœ ๋ถˆ๊ฐ€.


4. ์ฃผ์š” ๋‚ด์žฅ Hook

Hook ์ด๋ฆ„์„ค๋ช…
useState์ปดํฌ๋„ŒํŠธ ๋‚ด ์ƒํƒœ(state)๋ฅผ ์„ ์–ธํ•˜๊ณ  ๊ด€๋ฆฌ
useEffect์ƒ๋ช…์ฃผ๊ธฐ ๊ด€๋ฆฌ (๋ Œ๋”๋ง ์ดํ›„, ๋ณ€๊ฒฝ ๊ฐ์ง€, ์ •๋ฆฌ ์ž‘์—… ๋“ฑ)
useContextContext API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ „์—ญ ๋ฐ์ดํ„ฐ ์ ‘๊ทผ
useRefDOM ์ ‘๊ทผ ๋˜๋Š” ๋ Œ๋” ์‚ฌ์ด์—์„œ ์œ ์ง€๋˜๋Š” ๊ฐ’ ๊ด€๋ฆฌ
useMemo์—ฐ์‚ฐ ๊ฒฐ๊ณผ๋ฅผ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ํ•˜์—ฌ ์„ฑ๋Šฅ ์ตœ์ ํ™”
useCallbackํ•จ์ˆ˜๋ฅผ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ํ•˜์—ฌ ๋ถˆํ•„์š”ํ•œ ์žฌ๋ Œ๋”๋ง ๋ฐฉ์ง€
useReducer๋ณต์žกํ•œ ์ƒํƒœ ๋กœ์ง์„ ๋ฆฌ๋“€์„œ ํŒจํ„ด์œผ๋กœ ๊ด€๋ฆฌ
useLayoutEffectDOM์ด ๋ณ€๊ฒฝ๋œ ์งํ›„ ๋™๊ธฐ์ ์œผ๋กœ ์‹คํ–‰
useImperativeHandleref๋ฅผ ํ†ตํ•ด ๋ถ€๋ชจ๊ฐ€ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ’ ์ œ์–ด

5. ์˜ˆ์‹œ

โœ… useState & useEffect ์˜ˆ์ œ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import React, { useState, useEffect } from "react";

function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log(`ํ˜„์žฌ ์นด์šดํŠธ: ${count}`);
  }, [count]); // count ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋งŒ ์‹คํ–‰๋จ

  return (
    <button onClick={() => setCount(count + 1)}>
      ํด๋ฆญ ํšŸ์ˆ˜: {count}
    </button>
  );
}

export default Counter;

6. ์ปค์Šคํ…€ ํ›… (Custom Hook)

Hook์„ ์กฐํ•ฉํ•ด์„œ ์ƒˆ๋กœ์šด ํ›…์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. ์ด๋กœ์จ ์ƒํƒœ ๋กœ์ง์„ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ ๋‹ค.

์˜ˆ์‹œ: ์œˆ๋„์šฐ ํฌ๊ธฐ ๊ฐ์ง€ ํ›…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { useState, useEffect } from "react";

function useWindowSize() {
  const [size, setSize] = useState({
    width: window.innerWidth,
    height: window.innerHeight,
  });

  useEffect(() => {
    const handleResize = () => setSize({
      width: window.innerWidth,
      height: window.innerHeight
    });
    window.addEventListener("resize", handleResize);
    return () => window.removeEventListener("resize", handleResize);
  }, []);

  return size;
}

export default useWindowSize;

7. Hook์˜ ์žฅ์  ์š”์•ฝ

  • โœ… ์ฝ”๋“œ ๊ฐ„๊ฒฐ์„ฑ โ€” ํด๋ž˜์Šค ๋ฌธ๋ฒ•๋ณด๋‹ค ๋‹จ์ˆœ
  • ๐Ÿ” ๋กœ์ง ์žฌ์‚ฌ์šฉ โ€” ์ปค์Šคํ…€ ํ›…์œผ๋กœ ์ถ”์ƒํ™” ๊ฐ€๋Šฅ
  • โšก ์„ฑ๋Šฅ ์ตœ์ ํ™” โ€” useMemo, useCallback ๋“ฑ์œผ๋กœ ๋ถˆํ•„์š”ํ•œ ์—ฐ์‚ฐ ๊ฐ์†Œ
  • ๐Ÿงฉ ์ปดํฌ๋„ŒํŠธ ๊ตฌ์กฐ ๋‹จ์ˆœํ™” โ€” ๊ธฐ๋Šฅ ์ค‘์‹ฌ์œผ๋กœ ๋ถ„๋ฆฌ ๊ฐ€๋Šฅ

8. ์ฐธ๊ณ  ์ž๋ฃŒ

```

This post is licensed under CC BY 4.0 by the author.