Todo List성능 최적화 #05_useReducer 사용하기

Daniel Lim·2021년 4월 22일
0
post-thumbnail

useReducer 사용

useState 함수형 업데이트 대신 useReducer로도 onToggle, onRemove같은 함수들이 새로워지는 것을 해결할 수 있다.

useReducer는 기존 코드를 많이 고쳐야지만, 성능개선 외에도 state를 update하는 복잡한 로직들을 모으고 component 바깥에서도 관리할 수 있는 장점이 있다.

성능개선에 있어서는 useReducer와 useState 함수형 업데이트와 차이는 없다고 함.



useReducer 사용 ㄱㄱ

App.js

import React, { useReducer, useRef, useCallback } from 'react';
import TodoInsert from './components/TodoInsert';
import TodoList from './components/TodoList';
import TodoTemplate from './components/TodoTemplate';

function createBulkTodos() {
  const array = [];
  for (let i = 1; i <= 2500; i++) {
    array.push({
      id: 1,
      text: `할 일 ${i}`,
      checked: false,
    });
  }
  return array;
}



function todoReducer(todos, action) {	// todoReducer함수 만듬.
  switch (action.type) {
    case `INSERT`: // 새로 추가
      // { type: ‘INSERT‘, todo: { id: 1, text: ‘todo‘, checked: false } }
      return todos.concat(action.todo);
    case `REMOVE`: // 제거
      // { type: ‘REMOVE‘, id: 1 }
      return todos.filter(todo => todo.id !== action.id);
    case `TOGGLE`: // 토글
      // { type: ‘REMOVE‘, id: 1 }
      return todos.map(todo =>
        todo.id === action.id ? { ...todo, checked: !todo.checked } : todo,
      );
    default:
      return todos;
  }
}




const App = () => {
  const [todos, dispatch] = useReducer(todoReducer, undefined, createBulkTodos)
  //고유 값으로 사용될 아이디.
  // ref를 사용하여 변수 담기

  const nextId = useRef(2501);


  const onInsert = useCallback(
    (text) => {
      const todo = {
        id: nextId.current,
        text,
        checked: false,
      };
      dispatch({ type: 'INSERT', todo});
      nextId.current += 1; //nextId 1씩 더하기
    },
    [],
  );


  const onRemove = useCallback(
    (id) => {
      dispatch({ type: 'REMOVE', id });
    },
    [],
  );

  
  const onToggle = useCallback(
    (id) => {
      dispatch({ type: 'TOGGLE', id });
    },
    [],
  );

  return (
    <TodoTemplate>
      <TodoInsert onInsert={onInsert} />
      <TodoList todos={todos} onRemove={onRemove} onToggle={onToggle} />
    </TodoTemplate>
  );
};

export default App;


useState대신 useReducer로 import를 해줬다.
todoReducer함수를 만들었음.

onInsert, onRemove, onToggle 함수에 기존에 useState를 사용하면서 만들었던 setTodos 대신에

setTodos(todos => todos.concat(todo)); 이거에서
dispatch({ type: 'INSERT', todo}); 이렇게 입력했다.


useState와 useReducer 각각 초기값 설정시

const [todos, setTodos] = useState();

const [todos, dispatch] = useReducer(todoReducer, undefined, createBulkTodos)

useReducer를 사용할 때는 원래 두 번째 파라미터에 초기 상태를 넣어줘야함.
이번에는 undefined를 넣었고, 세번째 parameter에 "createBulkTodos"라고 입력을 했다.
왜냐면 이렇게 해야 처음 렌더링할때 createBulkTodos함수를 호출하게 된다.

참고링크: https://reactjs.org/docs/hooks-reference.html#usereducer

profile
웹개발 잘하고 싶어요

0개의 댓글

관련 채용 정보