[React] - useReducer

배정규·2020년 10월 30일
0

react

목록 보기
11/12

useReducer 훅을 사용하면 컴포넌트의 상태값을 리덕스의 리듀서처럼 관리할 수 있다. 그리고 여러 상태값을 관리할 때 좋고, useReducer와 콘텍스트 API를 이용하면 상위 컴포넌트에서 트리의 깊은 곳으로 이벤트 처리 함수를 쉽게 전달할 수 있다.

>사용법

  • useReducer 훅의 매개변수로 앞에서 작성한 리듀서와 초기 상태값을 입력한다.
  • useReducer 훅은 상태값과 dispatch 함수를 차례대로 반환한다.
  • state가 상태값이고 dispatch가 상태값을 변경시키는 함수다.
  • 이렇게 reducer 함수를 이용하면 상태값을 변경하는 로직을 분리할 수 있는 점이 장점이다.
import React, { useReducer } from "react";

export default function App() {
  const [state, dispatch] = useReducer(reducer, INITIAL_STATE);
  // state 가 상태값이고, dispatch가 상태값을 변경하는 함수이다. 
  return (
    <div>
      <p>{`name is ${state.name}`}</p>
      <p>{`age is ${state.age}`}</p>
      <input
        type="text"
        value={state.name}
        onChange={(e) =>
          dispatch({ type: "setName", name: e.currentTarget.value })
        }
      />
      <input
        type="number"
        value={state.age}
        onChange={(e) =>
          dispatch({ type: "setAge", age: e.currentTarget.value })
        }
      />
    </div>
  );
}

const INITIAL_STATE = { name: "empty", age: 0 };
const MAX_AGE = 50;
function reducer(state, action) {
  switch (action.type) {
    case "setName":
      return { ...state, name: action.name };
    case "setAge":
      if (action.age > MAX_AGE) {
        return { ...state, age: MAX_AGE };
      } else {
        return { ...state, age: action.age };
      }
    default:
      return state;
  }
}

트리의 깊은 곳으로 이벤트 처리 함수 전달하기

useReducer 훅이랑 Context API를 같이 이용하면 상위 컴포넌트에서 트리의 깊은 곳으로 이벤트처리 함수를 쉽게 전달할 수 있습니다.
이러한 패턴으로 꽤 괜찮게 상태값을 관리할 수 있기 때문에 리덕스와 같은 별도의 라이브러리를 사용하지 않고 리액트만으로 이렇게 작성할 수가 있다.

>사용법

  • dispatch 함수를 전달해 주는 콘텍스트 객체를 생성한다.
  • Provider를 통해서 dispatch 함수를 데이터로 전달한다.
  • SomeComponent 하위에 있는 모든 커모넌트에서는 콘텍스트를 통해서 dispatch 함수를 호출할 수 있다.
import React, { useReducer } from "react";

export const ProfileDispatch = React.createContext(null);
// Context API 를 이용해서 ProfileDispatch라는 Context 만들어준다.

export default function App() {
  const [state, dispatch] = useReducer(reducer, INITIAL_STATE);
  return (
    <div>
      <p>{`name is ${state.name}`}</p>
      <p>{`age is ${state.age}`}</p>
      <ProfileDispatch.Provider value={dispatch}>
        <SomeComponent />
      </ProfileDispatch.Provider>
    </div>
  );
}

const INITIAL_STATE = { name: "empty", age: 0 };
function reducer(state, action) {
  switch (action.type) {
    case "setName":
      return { ...state, name: action.name };
    case "setAge":
      return { ...state, age: action.age };
    default:
      return state;
  }
}
profile
Seize the day

0개의 댓글