개념정리/React

상태 관리에 사용되는 Hook

과부하가보자구 2023. 12. 3. 16:55

 

외부 라이브러리없이 React 제공하는 만으로 상태관리를 구현하기 위해 사용한다. 함수형 컴포넌트에 상태를 두고 여러 컴포넌트 데이터와 데이터 변경 함수를 공유하는 방식으로 상태를 관리하게 된다.


useState

  • 단순한 하나의 상태를 관리하기에 적합하다.
const [ state, setState] = useState(initState| initFn)
  • state가 바뀌면, state를 사용하는 컴포넌트를 리렌더한다.
  • useEffect와 함께, state에 반응하는 훅을 구축한다.

useState 활용한 상태 관리

  • 상위 컴포넌트에서 state와 state변경 함수를 정의하고, 그 state나 변경 함수를 사용하는 컴포넌트까지 prop으로 내려주는 패턴이다.(state를 조작하는 함수를 하위 컴포넌트로 넘겨야 함)
  • state가 변경되면, 중간에 state를 넘기기만 하는 컴포넌트들도 모두 리렌더링된다.(nested되었다고 하더라도, 변경이 있으면 리렌더링을 트리거함)
  • 상태와 상태에 대한 변화가 단순하거나, 상대적으로 소규모 앱에서 사용하기에 적합하다.

useRef

  • 상태가 바뀌어도 리렌더링하지 않는 상태를 정의한다. (즉, 상태가 UI의 변경과 관계없을 때 사용_setTimeout의 timerId 저장)
  • uncontrolled component의 상태를 조작하는 등, 리렌더링을 최소화하는 상태 관리에 사용된다. ex) Dynamic Form 예시

useContext

  • 컴포넌트와 컴포넌트간의 상태를 공유할 때 사용한다.
  • 부분적인 컴포넌트들의 상태 관리, 전체 앱의 상태 관리를 모두 구현한다.
  • Context Provider 안에서 렌더링되는 컴포넌트는, useContext를 이용해 깊이 nested된 컴포넌트라도 바로 context value를 가져온다.
  • context value가 바뀌면 그 context를 사용하는 내부의 모든 컴포넌트는 리렌더링된다.(데이터간의 영향을 주의해야 함)
  • context API를 사용할 수 있는 Hook이다.

useContext를 활용한 상태 관리

  • Provider단에서 useReducer 를 사용하여 상태를 정의하고, 직접 상태와 변경 함수를 사용하는 컴포넌트에서 useContext를 이용해 바로 상태와 변경함수를 가져와 사용하는 패턴이다.
    • 하위 컴포넌트의 props로 상태를 넘겨 참조하거나, useContext를 이용하여 상태를 받아올 수 있다.
    • 하위 컴포넌트에 dispatch를 넘겨 상태를 조작할 수 있다.
  • useReducer와 함께, 복잡한 상태와 상태에 대한 변경 로직을 두 개이상의 컴포넌트에서 활용하도록 구현하는 것이 가능하다.
    • useState, useReducer 등 다른 hook과 함께 사용이 가능하다.
  • state는 필요한 곳에서만 사용하므로, 불필요한 컴포넌트 리렌더링을 방지한다.
  • Prop Drilling(Plumbing)을 방지하여 컴포넌트간 결합도를 낮춰준다.

useReducer

  • useState보다 복잡한 상태를 다룰 때 사용한다.
  • 별도의 라이브러리없이 flux pattern에 기반한 상태 관리를 구현한다.
const [state, dispatch] = useReducer(reducer, initState)

// useReducer()의 인자들을 모두 필수 값_reducer, 초기값

// dispatch(action) -> reducer -> state -> state값을 사용하는 모든 것에 영향
  • nested state등 복잡한 여러 개의 상태를 한꺼번에 관리하거나, 어떤 상태에 여러가지 처리를 적용할 때 유용하다.
  • 상태가 복잡하다면, useState에 관한 callback을 내려주는 것보다 dispatch를 prop으로 내려 리렌더링을 최적화하는 것을 권장한다.

import React, { useReducer } from 'react';
import './App.css';

// count의 초기 state를 0으로 설정하세요.
// 초기값 설정
const initialState = {
  count: 0,
};

// reducer함수설정
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 App() {
  // ⭐useReducer()를 호출하세요.
  const [state, dispatch] = useReducer(reducer, initialState);
  
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
    </>
  );
}
export default App;

 

✔️ reducer 함수는 현재 상태 객체와 수행할 행동 객체를 인자로 받아서 새로운 상태 객체를 반환하는 함수입니다.

 

✔️dispatch 함수는 컴포넌트 내에서 상태 변경을 일으키기 위해서 사용되는데 인자로 reducer 함수에 넘길 행동 객체를 받습니다.

 

행동 객체는 일반적으로 어떤 부류의 행동인지를 나타내는 type이나 해당 행동과 관련된 데이터를 담고 있습니다.

 

다시 말해, 컴포넌트에서 dispatch 함수에서 넘겨준 행동을 하면 reducer 함수가 이 행동에 따라서 상태를 변경해줍니다.

 

 

 

#엘리스트랙 #엘리스트랙후기 #리액트네이티브강좌 #온라인코딩부트캠프 #온라인코딩학원 #프론트엔드학원 #개발자국비지원 #개발자부트캠프 #국비지원부트캠프 #프론트엔드국비지 #React #Styledcomponent #React Router Dom #Redux #Typescript #Javascript