[React] Immutability

woohobi·2022년 3월 29일
0

불변성과 React

React는 Rerender 과정에서 현재의 props, state와 nextProps, nextState 를 비교할 때, 얕은 비교(shallow comparison)에 의존한다. 따라서, state를 변경할때 불변성을 지켜주는 것이 성능 뿐만 아니라 에러 방지에도 중요한 역할을 하는데 올바른 변경 방법을 정리하였습니다.
이해를 위해 간단한 toDoList를 만들었는데 사용한 코드는 github 에서 확인할 수 있습니다.

데이터

const toDoList = [
  {
    id: 1,
    task: "Check list",
    isComplete: false,
  },
  ...

데이터는 id, task, isComplete으로 구성된 간단한 배열입니다.

 위와 같은 간단한 toDoList에 새로운 항목을 추가해보겠습니다.

항목 추가

const onAdd = (event:React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    const toDo= {
      id: inputRef.current,
      task: input,
      isComplete: false,
    }
    setToDos([...toDos, toDo]);
  ...
}

새로운 항목을 추가할 때는, push와 같이 기존 배열에 항목을 추가하는 대신, spread operator를 사용하거나 concat을 사용해서 새로운 배열을 만들어줍니다.

항목 제거

const onDelete = (id:number) => {
    setToDos(toDos.filter(item => item.id !== id));
};

filter 함수는 조건이 맞는 항목들을 새로운 배열을 만들어 return 합니다.

항목 변경

const onEdit = (id:number) => {
  setToDos(
    toDos.map(toDo =>
              toDo.id === id ? {...toDo, isComplete: !toDo.isComplete} : toDo
             )
  );
};

map 함수는 모든 항목들을 순회하고 지정한 동작을 수행하고 새로운 배열을 return 한다는 점에서 forEacth와 다르기 때문에 map 함수를 사용합니다.

결론

추가, 제거, 변경에서 모두 살펴보았듯이 react는 얕은 비교를 하기 때문에, 배열을 비교할 때 기존항목을 추가, 변경하는 방식보다 새롭게 할당하는 방식을 사용해야 합니다. 세 가지 모두 새로운 배열을 생성하고 있는 부분을 봐주시면 좋을 것 같습니다. 객체 구조가 복잡해지고 깊어지면 Immer 과 같은 라이브러리의 도움을 받는 것도 좋은 방법인 것 같습니다.

profile
CDD - Coffee Driven Development

0개의 댓글