useReducer 마이그레이션 전에 한 번 더 보고, 마이그레이션 해 봄

const job = '프론트엔드';·2023년 10월 4일
0
post-thumbnail

useReducer는 상태관리 훅이다.

useState가 있는데, 왜 useReducer를 또 공부해야 하는가?

공통점

  • 새로운 State를 생성하고, State를 업데이트 시키는 함수를 제공

차이점

useState

  • 상태관리 로직을 컴포넌트 내부에 작성해야 함
  • 그래서 업데이트 시키는 상태관리 로직들이 복잡해지고, 길어지면 컴포넌트 내부에 상당히 많은 코드들을 작성해야 하고, 가독성이 너무나 떨어지게 됨

useReducer

  • 컴포넌트 외부에 State 관리 로직 분리 가능
const [count, dispatch] = useReducer(리듀서함수, 상태의 초깃값)
function reducer(현재상태, action ) {
	if(action.type === "MINUS") {
      return 현재상태 - action.data
    }
}
  • reducer함수는 첫번째 인자로 현재상태, 두번째 인자로는 action 객체가 전달
  • 그러면 action.type 조건에 따라 return으로 전달된 내용을 수행
const [count, dispatch] = useReducer(reducer, 0)
  • count 변수의 상태를 변화시키기 위한 useReducer
  • count 변수의 초깃값은 0
  • dispatch는 상태변화를 발동시키기 위한 트리거, 그러니깐 상태변화를 유발하기만 하고 직접 상태변화를 처리하지 않는 상태
  • 상태변화는 reducer 함수가 처리함
 	<h4>{count}</h4>
      <button
        onClick={() => {
          dispatch({
            type: "MINUS",
            data: 1,
          });
        }}
      >
        -
      </button>

작동원리

  1. onClick 이벤트에 콜백 함수를 실행하도록 해놓고
onClick = {() => {}}
  1. dispatch를 호출(트리거)해서, reducer 상태변화 함수를 실행시킴
onClick = {() => {
	dispatch()
}}
  1. dispatch()안에는 어떤 상태변화를 원하는지 인수(객체형태)로 전달해줘야 함
onClick = {() => {
	dispatch({
    	type:"MINUS",
      	data:1,
    })
}}

todolist에 useReducer 적용해보기

1단계: useState 지우기

const [todos, dispath] = useReducer(reducer, mockData)

2단계: reducer 함수 만들기

function reducer() {}
function reducer(state, action) {
  if (action.type === "CREATE") {
    return [...state, action.data];
  }
  if (action.type === "UPDATE") {
    return state.map((it) =>
      it.id === action.data ? { ...it, isDone: !it.isDone } : it
    );
  }
  if (action.type === "DELETE") {
    return state.filter((it) => it.id !== action.data);
  }
}

3단계: 기존 setTodos를 호출했던 부분에 dispatch()를 호출

	const onUpdate = (targetId) => {
    dispatch({
      type: "UPDATE",
      data: targetId,
    });
    // setTodos(
    //   todos.map((todo) => {
    //     if (todo.id === targetId) {
    //       return {
    //         ...todo,
    //         isDone: !todo.isDone,
    //       };
    //     } else {
    //       return todo;
    //     }
    //   })
    // );
  };
  const onUpdate = (targetId) => {
    dispatch({
      type: "UPDATE",
      data: targetId,
    });
    // setTodos(
    //   todos.map((todo) => {
    //     if (todo.id === targetId) {
    //       return {
    //         ...todo,
    //         isDone: !todo.isDone,
    //       };
    //     } else {
    //       return todo;
    //     }
    //   })
    // );
  };
  const onDelete = (targetId) => {
    dispatch({
      type: "DELETE",
      data: targetId,
    });

    // setTodos(todos.filter((todo) => todo.id !== targetId));
  };

전체적으로 컴포넌트 내에 적었던(주석처리 된 코드) 코드가 useReducer사용으로 간략해진 것을 확인할 수 있음

profile
`나는 ${job} 개발자`

0개의 댓글