avatar
Published on

React Hooks Api (2)

Author
  • avatar
    Name
    yceffort

useReducer

const [state, dispatch] = useReducer(reducer, initialArg, init)

useState์˜ ๋Œ€์ฒด ํ•จ์ˆ˜๋‹ค. ๋‹ค์ˆ˜์˜ ํ•˜์œ— ๊ฐ’์„ ๋งŒ๋“œ๋Š” ๋ณต์žกํ•œ ๋กœ์ง, ํ˜น์€ ๋‹ค์Œ state๊ฐ€ ์ด์ „ state์˜ ์˜์กด์ ์ธ ๊ฒฝ์šฐ์— ์“ด๋‹ค. ๋ญ๊ฐ€ ๋ญ”์ง€ ๋ชจ๋ฅด๊ฒ ์œผ๋‹ˆ๊นŒ ์˜ˆ์ œ๋ฅผ ๋ณด์ž.

useState๋ฅผ ์“ฐ๊ธฐ์ „

function Counter({initialCount}) {
  const [count, setCount] = useState(initialCount)
  return (
    <>
      Count: {count}
      <button onClick={() => setCount(initialCount)}>Reset</button>
      <button onClick={() => setCount((prevCount) => prevCount + 1)}>+</button>
      <button onClick={() => setCount((prevCount) => prevCount - 1)}>-</button>
    </>
  )
}
const initialState = {count: 0}

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1}
    case 'decrement':
      return {count: state.count - 1}
    default:
      throw new Error()
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState)
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
    </>
  )
}
function init(initialCount) {
  return {count: initialCount}
}

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1}
    case 'decrement':
      return {count: state.count - 1}
    case 'reset':
      return init(action.payload)
    default:
      throw new Error()
  }
}

function Counter({initialCount}) {
  const [state, dispatch] = useReducer(reducer, initialCount, init)
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'reset', payload: initialCount})}>
        Reset
      </button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
    </>
  )
}

์˜ˆ์ œ๋ฅผ ๋ณด๋‹ˆ ๋Œ€์ถฉ ๊ฐ์ด ์˜จ๋‹ค. dispatch๋ฅผ ํ†ตํ•ด์„œ state๊ฐ’์— ๋ณ€ํ™”๋ฅผ ์ฃผ์ง€ ์•Š๊ณ  state๊ฐ’ ๋ณ€ํ™”์— ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ์ค„ ์ˆ˜ ์žˆ๊ณ , ์ด ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ์ด์šฉํ•ด ์—ฌ๋Ÿฌ๊ฐœ์˜ state์— ๋ณ€ํ™”๋ฅผ ์ค„ ์ˆ˜๋„ ์žˆ๋‹ค.

useCallback

๋ฉ”๋ชจ์ด์ œ์ด์…˜๋œ ์ฝœ๋ฐฑ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

const memoizedCallback = useCallback(() => {
  doSomething(a, b)
}, [a, b])

๋™์ผํ•œ ์ฝœ๋ฐฑ์„ ๋ฐ”๋ผ๋ด์•ผํ•˜๋Š” ์ž์‹ ์ปดํฌ๋„ŒํŠธ์—๊ฒŒ ์‚ฌ์šฉํ•  ๋•Œ ์œ ์šฉํ•˜๋‹ค.

useMemo

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b])

๋ฉ”๋ชจ์ด์ œ์ด์…˜๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. useMemo๋Š” ์˜์กด์„ฑ์ด ๋ณ€๊ฒฝ๋˜์—ˆ์„ ๋•Œ๋งŒ, ๋ฉ”๋ชจ์ œ์ด์…˜๋œ ๊ฐ’์„ ๋‹ค์‹œ ๊ณ„์‚ฐํ•  ๊ฒƒ์ด๋‹ค.

useRef

const refContainer = useRef(initialValue)

function TextInputWithFocusButton() {
  const inputEl = useRef(null)
  const onButtonClick = () => {
    // `current` points to the mounted text input element
    inputEl.current.focus()
  }
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  )
}

useRef๋Š” .current์— ๋ณ€๊ฒฝ๊ฐ€๋Šฅํ•œ ref๊ฐ’์„ ๋‹ด์„ ์ˆ˜ ์žˆ๋‹ค. ๋ถ€๋ชจ ํด๋ž˜์Šค์—์„œ ํŠน์ • dom๊ฐ์ฒด๋ฅผ ๊ณ„์† ์ถ”์ ํ•ด์•ผํ•  ๋•Œ ์œ ์šฉํ•˜๋‹ค. ๋‹ค๋งŒ .current๋ฅผ ๋ณ€๊ฒฝํ•œ๋‹ค๊ณ  ํ•ด์„œ ๋ฆฌ๋ Œ๋”๋ง์ด ์ผ์–ด๋‚˜์ง€๋Š” ์•Š๋Š”๋‹ค.