25.06.12 - se5ri/React GitHub Wiki

ch04-hooks 02 useEffect

useEffect

  • μ»΄ν¬λ„ŒνŠΈ 생λͺ…μ£ΌκΈ° 이벀트λ₯Ό λ“±λ‘ν•˜κΈ° μœ„ν•œ ν›…
  • 클래슀 기반 μ»΄ν¬λ„ŒνŠΈμ—μ„œλŠ” μ•„λž˜ λ©”μ†Œλ“œλ₯Ό μ˜€λ²„λΌμ΄λ“œν•΄μ„œ κ΅¬ν˜„
    • componentDidMount(): μ»΄ν¬λ„ŒνŠΈκ°€ 마운트 μ™„λ£Œλ˜κ³  λΈŒλΌμš°μ € DOM νŠΈλ¦¬μ— 반영된 ν›„ 호좜
    • componentDidUpdate(): λΈŒλΌμš°μ € DOM μ—…λ°μ΄νŠΈ μ™„λ£Œ ν›„ 호좜
    • componentWillUnmount(): μ»΄ν¬λ„ŒνŠΈκ°€ μ‚­μ œλ˜κΈ° 직전에 호좜
    • ...
  • useEffectμ—μ„œ 주둜 κ΅¬ν˜„ν•˜λŠ” κΈ°λŠ₯
    • μ»΄ν¬λ„ŒνŠΈμ˜ λ Œλ”λ§ μž‘μ—… μ™Έμ˜ 뢀가적인 μž‘μ—…
      • 타이머 μ„€μ •
      • λ‘œκΉ…
    • μ»΄ν¬λ„ŒνŠΈμ˜ λ Œλ”λ§ 이후에 μ²˜λ¦¬ν•  μž‘μ—…
      • DOM μˆ˜λ™ μ‘°μž‘
    • side effectκ°€ λ°œμƒν•˜λŠ” μž‘μ—…(μ»΄ν¬λ„ŒνŠΈλ₯Ό 순수 ν•¨μˆ˜λ‘œ μœ μ§€)
      • 데이터 fetching

API

useEffect(setup, dependencies?);

λ§€κ°œλ³€μˆ˜

  • setup: μ»΄ν¬λ„ŒνŠΈκ°€ 마운트(1-4), μ—…λ°μ΄νŠΈ(2-5), 제거(3-1) 될 λ•Œ ν˜ΈμΆœλ˜λŠ” ν•¨μˆ˜

    • setup이 ν•¨μˆ˜λ₯Ό λ¦¬ν„΄ν•˜λ©΄, λ¦¬ν„΄ν•œ ν•¨μˆ˜λ₯Ό cleanup이라고 λΆ€λ₯΄λ©°, μ»΄ν¬λ„ŒνŠΈκ°€ μ—…λ°μ΄νŠΈλ˜κ±°λ‚˜ μ–Έλ§ˆμš΄νŠΈ 될 λ•Œ 호좜됨 (cleanup이 λ¨Όμ € μ‹€ν–‰λ˜κ³  setup이 뒀에 싀행됨)
  • dependencies (선택): 의쑴 객체 λ°°μ—΄

    • μ»΄ν¬λ„ŒνŠΈκ°€ μ—…λ°μ΄νŠΈλ  λ•Œ setup ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν• μ§€ 말지 μ—¬λΆ€λ₯Ό κ²°μ •ν•˜λŠ”λ° μ‚¬μš©
    • μ»΄ν¬λ„ŒνŠΈκ°€ 마운트될 λ•ŒλŠ” dependencies 여뢀와 상관없이 setup이 호좜됨
    • dependenciesλ₯Ό μƒλž΅ν•˜λ©΄, μ»΄ν¬λ„ŒνŠΈκ°€ μ—…λ°μ΄νŠΈλ  λ•Œ 항상 setup이 호좜됨
    • dependencies에 빈 배열을 μ§€μ •ν•˜λ©΄ μ—…λ°μ΄νŠΈμ—μ„œλŠ” ν˜ΈμΆœλ˜μ§€ μ•ŠμŒ
    • dependenciesλ₯Ό μ§€μ •ν•˜λ©΄, ν•΄λ‹Ή 값듀이 변경될 λ•Œλ§Œ setup ν•¨μˆ˜κ°€ 호좜됨

πŸ“œ 02 useEffect - side effect 관리

ch04-hooks 03 useReducer

useReducer

  • useState와 λΉ„μŠ·ν•˜μ§€λ§Œ, μƒνƒœ 관리가 더 λ³΅μž‘ν•œ κ²½μš°μ— μ‚¬μš©
  • useStateλ₯Ό μ‚¬μš©ν•  λ•Œ μ»΄ν¬λ„ŒνŠΈ λ‚΄λΆ€μ—μ„œ μƒνƒœ λ³€κ²½ λ‘œμ§μ„ κ΅¬ν˜„ν•΄μ•Ό ν•˜κΈ° λ•Œλ¬Έμ— μ»΄ν¬λ„ŒνŠΈκ°€ λ³΅μž‘ν•΄μ§
  • μ»΄ν¬λ„ŒνŠΈ μ™ΈλΆ€μ—μ„œ μƒνƒœ 관리λ₯Ό ν•˜κ³  싢을 λ•Œ 유용
  • μ—¬λŸ¬ μ»΄ν¬λ„ŒνŠΈκ°€ μœ μ‚¬ν•œ μƒνƒœ κ΄€λ ¨ λ‘œμ§μ„ μ‚¬μš©ν•  경우 κΈ°λŠ₯을 κ³΅μœ ν•  수 있음
  • state 값은 λΆˆλ³€μ„±μ΄ μžˆμ–΄ μƒνƒœ λ³€κ²½μ˜ 내역을 좔적할 수 있음
  • λ¦¬λ“€μ„œλŠ” 순수 ν•¨μˆ˜λ‘œ λ§Œλ“€μ–΄μ•Ό 함
    • μž…λ ₯ 값이 λ™μΌν•˜λ©΄ 좜λ ₯ 값도 동일
    • μ™ΈλΆ€ 값에 영ν–₯을 μ£Όκ±°λ‚˜ λ°›μœΌλ©΄ μ•ˆ 됨
  • λ¦¬λ“€μ„œλ₯Ό μ‚¬μš©ν•˜μ—¬ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ „μ—­ μˆ˜μ€€μ˜ μƒνƒœλ₯Ό κ΄€λ¦¬ν•˜λŠ” λΌμ΄λΈŒλŸ¬λ¦¬κ°€ Redux

API

function reducer(state, action){ ... }
const [state, dispatch] = useReducer(reducer, initialArg, init?);

λ§€κ°œλ³€μˆ˜

  • reducer: state와 action을 인자둜 λ°›μ•„ μƒˆλ‘œμš΄ stateλ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜
    • state: λ¦¬λ“€μ„œμ— μ „λ‹¬λ˜λŠ” μƒνƒœκ°’
    • action: dispatch에 μ „λ‹¬ν•œ μΈμžκ°’μœΌλ‘œ, μˆ˜ν–‰ν•  μž‘μ—…μ˜ μ’…λ₯˜μ™€ ν•„μš”ν•œ μΈμžκ°’μ„ ν¬ν•¨ν•œ 객체
  • initialArg: 초기 μƒνƒœλ‘œ μ§€μ •ν•  κ°’
  • init(선택): initialArgλ₯Ό 인자둜 λ°›κ³ , λ¦¬ν„΄ν•œ 값이 초기 μƒνƒœλ‘œ μ§€μ •λ˜λŠ” ν•¨μˆ˜

리턴값

  • state: μƒνƒœκ°’μ΄ μ €μž₯된 getter
  • dispatch: μƒνƒœκ°’μ„ λ³€κ²½ν•˜λŠ” setter ν•¨μˆ˜. dispatch에 μ „λ‹¬ν•œ μΈμžκ°’μ΄ reducer의 λ‘λ²ˆμ§Έ μΈμžκ°’(action)으둜 전달됨

μƒνƒœ 관리: useState vs. useReducer

μ½”λ“œ 크기

  • useReducerλ₯Ό μ‚¬μš©ν•˜λ©΄ reducer ν•¨μˆ˜μ™€ dispatch μ•‘μ…˜μ„ μž‘μ„±ν•΄μ•Ό ν•˜κΈ° λ•Œλ¬Έμ— 기본적으둜 μ½”λ“œ 크기가 useStateλ₯Ό μ‚¬μš©ν•  λ•Œλ³΄λ‹€ λ§Žμ•„μ§

    const TodoReducer = function(state, action) {
      // μƒνƒœ λ³€κ²½ 둜직
    };
    itemListDispatch({ type: 'TOGGLE', item: { _id }});
  • μ—¬λŸ¬ 이벀트 ν•Έλ“€λŸ¬κ°€ λΉ„μŠ·ν•œ μƒνƒœ 관리 λ‘œμ§μ„ κ°€μ§€κ³  μžˆλ‹€λ©΄ reducer ν•¨μˆ˜μ— κ³΅ν†΅μœΌλ‘œ μž‘μ„±ν•΄μ„œ μ½”λ“œλ₯Ό 쀄일 수 있음

    const TodoReducer = function(state, action){
      const index = state.findIndex(item => item._id === action.item._id);
      switch(action.type){
        case 'TOGGLE':
          return produce(state, draft => {
            draft[index].done = !draft[index].done;
          });
        default:
        case 'DELETE':
          return produce(state, draft => {
            draft.splice(index, 1);
          });
      }
    };

가독성

  • μƒνƒœ λ³€κ²½ 둜직이 λ³΅μž‘ν•˜κ³  μ—¬λŸ¬ 이벀트 ν•Έλ“€λŸ¬μ—μ„œ λΉ„μŠ·ν•œ λ‘œμ§μ„ μ‚¬μš©ν•΄μ•Ό ν•œλ‹€λ©΄, useState둜 μƒνƒœλ₯Ό 직접 κ΄€λ¦¬ν•˜κΈ°λ³΄λ‹€λŠ” useReducer에 μƒνƒœ λ³€κ²½ λ‘œμ§μ„ μ§‘μ€‘μ‹œν‚€κ³  μ»΄ν¬λ„ŒνŠΈμ™€ λΆ„λ¦¬ν•˜λ©΄ μ»΄ν¬λ„ŒνŠΈλ₯Ό λ‹¨μˆœν™”ν•  수 있음

디버깅

  • useStateλŠ” μƒνƒœ λ³€κ²½ 도쀑 였λ₯˜κ°€ λ°œμƒν•˜λ©΄ μ—¬λŸ¬ 이벀트 ν•Έλ“€λŸ¬λ₯Ό 확인해야 ν•˜μ§€λ§Œ, useReducerλŠ” μƒνƒœ λ³€κ²½ 둜직이 ν•œ 곳에 있기 λ•Œλ¬Έμ— 디버깅이 νŽΈν•¨

ν…ŒμŠ€νŠΈ

  • reducer ν•¨μˆ˜λŠ” μ»΄ν¬λ„ŒνŠΈμ™€ 독립적인 순수 ν•¨μˆ˜μ΄κΈ° λ•Œλ¬Έμ— λ”°λ‘œ ν…ŒμŠ€νŠΈκ°€ κ°€λŠ₯함

νƒ€μž… μ•ˆμ •μ„±

  • action의 νƒ€μž…μ„ λͺ…ν™•ν•˜κ²Œ μ •μ˜

개인 μ„ ν˜Έλ„μ— 따름

πŸ“œ 03 useReducer - μƒνƒœ 관리 λ‘œμ§μ„ ν•œκ³³μ—

ch04-hooks 04 useRef

useRef

  • μ»΄ν¬λ„ŒνŠΈκ°€ λ‹€μ‹œ λ Œλ”λ§λ˜λ”λΌλ„ κΈ°μ‘΄ μƒνƒœκ°’μ„ μœ μ§€ν•˜λŠ” λ³€μˆ˜λ₯Ό 생성
  • ν•¨μˆ˜ 내뢀에 μ •μ˜ν•˜λŠ” μ§€μ—­ λ³€μˆ˜λŠ” μ»΄ν¬λ„ŒνŠΈκ°€ λ‹€μ‹œ λ Œλ”λ§λ˜λ©΄(ν•¨μˆ˜ 재호좜) 값이 μ΄ˆκΈ°ν™” 됨
  • useStateλŠ” 값이 λ³€κ²½λ˜λ©΄ μ»΄ν¬λ„ŒνŠΈκ°€ λ‹€μ‹œ λ Œλ”λ§λ˜μ§€λ§Œ useRefλŠ” 값이 λ³€κ²½λ˜μ–΄λ„ μ»΄ν¬λ„ŒνŠΈκ°€ λ‹€μ‹œ λ Œλ”λ§λ˜μ§€ μ•ŠμŒ
  • JSX νƒœκ·Έμ— ref 속성을 μΆ”κ°€ν•˜λ©΄ λΈŒλΌμš°μ € DOM μ—˜λ¦¬λ¨ΌνŠΈμ— 직접 μ ‘κ·Ό κ°€λŠ₯
    • 포컀슀, λ―Έλ””μ–΄ μž¬μƒ, μ• λ‹ˆλ©”μ΄μ…˜ μ‹€ν–‰ λ“±κ³Ό 같은 μž‘μ—…μ€ useRefλ₯Ό μ‚¬μš©ν•΄ λΈŒλΌμš°μ € DOM에 직접 μ ‘κ·Όν•˜μ—¬ μ œμ–΄ν•΄μ•Ό 함

API

const ref = useRef(initialValue);

λ§€κ°œλ³€μˆ˜

  • initialValue: μ΄ˆκΈ°κ°’

리턴값

  • currentλΌλŠ” μƒνƒœκ°’ λ˜λŠ” DOM μš”μ†Œκ°€ μžˆλŠ” 속성 ν•˜λ‚˜κ°€ μ •μ˜λœ 객체

input μš”μ†Œμ˜ κ°’ μ§€μ •: useState vs. useRef

useState μ‚¬μš©

  • value μ†μ„±μœΌλ‘œ μƒνƒœκ°’ μ§€μ •
  • λ¦¬μ•‘νŠΈμ—μ„œ 직접 μƒνƒœκ΄€λ¦¬λ₯Ό ν•˜λŠ” μ œμ–΄ μ»΄ν¬λ„ŒνŠΈλ₯Ό κ΅¬ν˜„
  • input 값이 λ³€κ²½λ˜λŠ” μ¦‰μ‹œ λ¦¬λ Œλ”λ§ λ˜μ–΄μ•Ό ν• λ•Œ
    • λ¦¬λ Œλ”λ§μ΄ 자주 λ˜λ―€λ‘œ μ˜€λ²„ν—€λ“œ λ°œμƒ
μ˜ˆμ‹œ
function App(){
  const [msg, setMsg] = useState('');
  return (
    <>
      <h1>01 useState - μƒνƒœ 관리</h1>
      <div>
        <input type="text" value={ msg } onChange={ e => setMsg(e.target.value) } />
        <br/>
        <span>μž…λ ₯ λ©”μ„Έμ§€: { msg }</span>
      </div>
    </>
  );
}

useRef μ‚¬μš©

  • defaultValue μ†μ„±μœΌλ‘œ μ΄ˆκΈ°κ°’ μ§€μ •
  • λΈŒλΌμš°μ €μ—μ„œ μž…λ ₯값을 κ΄€λ¦¬ν•˜λŠ” λΉ„μ œμ–΄ μ»΄ν¬λ„ŒνŠΈλ₯Ό κ΅¬ν˜„
  • input 값이 λ³€κ²½ λ˜μ–΄λ„ λ¦¬λ Œλ”λ§ 될 ν•„μš”κ°€ μ—†μ„λ•Œ
    • λ¦¬λ Œλ”λ§μ΄ λ˜μ§€ μ•ŠμœΌλ―€λ‘œ μ„±λŠ₯ μ΅œμ ν™”
μ˜ˆμ‹œ
function Counter() {
  const step = useRef(1);

  return (
    <div id="counter">
      <input type="number" defaultValue={ step.current } onChange={ e => step.current = Number(e.target.value) } />
      <Button color="red">-</Button>
      <Button>0</Button>
      <Button color="blue">+</Button>
      <span>0</span>
    </div>
  );
}

πŸ“œ 04 useRef-값이 μœ μ§€λ˜λŠ” 데이터 관리, DOM μ—˜λ¦¬λ¨ΌνŠΈ μ°Έμ‘°

⚠️ **GitHub.com Fallback** ⚠️