본문 바로가기
엘리스 AI 트랙 4기/elice AI track

[8주차] 상태 관리에 사용되는 Hook

by _sweep 2022. 3. 11.

3월 11일 자 학습 내용 정리입니다.

 

 

상태 관리에 사용되는 Hook

외부 라이브러리 없이 React가 제공하는 Hook 만으로도 상태 관리를 구현할 수 있는데,  함수형 컴포넌트에 상태를 두고 여러 컴포넌트 간 데이터와 데이터 변경 함수를 공유하는 방식으로 상태를 관리한다.

 

✔️ useState

useState는 단순하게 하나의 상태를 관리하기 적합하다.
state가 바뀌면 state를 사용하는 컴포넌트를 재렌더링하며 useEffect와 함께 state에 반응하는 Hook을 구축한다.

 

const [state, setState] = useState(initValue | initFn)

 

✔️ useRef

useRef는 상태가 바뀌어도 재렌더링하지 않는 상태를 정의한다.
즉, setTimeout의 timerId와 같이 상태가 UI의 변경과 관계없을 때 사용되며 uncontrolled component(ex. input과 같은 DOM Element)의 상태를 조작하는 등 재렌더링을 최소화하는 상태 관리에 사용된다.

 

const refContainer = useRef(initialValue);

 

useRef는 .current 프로퍼티로 전달된 인자(initialValue)로 초기화된 변경 가능한 ref 객체를 반환한다.

 

✔️ useContext

useContext는 컴포넌트와 컴포넌트 간 상태를 공유할 때 사용한다.
부분적인 컴포넌트들의 상태 관리, 전체 앱의 상태 관리를 모두 구현할 수 있다.

 

import React, { createContext, useContext } from 'react';

const MyContext = createContext();
const value = useContext(MyContext);

 

useContext는 context 객체(React.createContext에서 반환된 값)를 받아 그 context의 현재 값을 반환한다.

context의 현재 값은 트리 안에서 이 Hook을 호출하는 컴포넌트에 제일 가까이 있는 <MyContext.Provider>의 value prop에 의해 결정된다.


만약 부모 컴포넌트가 Context Provider 안에서 렌더링되었다면 useContext를 이용해 아무리 깊이 있는 자식 컴포넌트일지라도 바로 부모 컴포넌트의 context value를 가져올 수 있다.
하지만 context value가 바뀌면 내부 컴포넌트는 모두 재렌더링 된다.

 

✔️ useReducer

useReducer는 useState보다 복잡한 상태를 다룰 때 사용한다.
별도의 라이브러리없이 Flux 패턴에 기반한 상태 관리를 구현할 수 있다.

 

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


dispatch는 action을 reducer에 전달하고 reducer는 업데이트된 내용을 state에 반영한다.

 

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: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}


여러 개의 상태를 한꺼번에 관리하거나 하나의 상태에 여러 가지 처리를 적용할 때 유용하다.
상태가 복잡하다면 useState에 관련된 callback을 내려주는 것보다 dispatch를 prop으로 내려 재렌더링을 최적화하는 것을 권장한다.

 

 

🔍 참조

Hooks API Reference https://ko.reactjs.org/docs/hooks-reference.html

 

 

댓글