Toolkit과 Immer에 대해서

BirdsOnTree·2022년 9월 6일
0

React

목록 보기
6/10
post-thumbnail

거의 매일같이 toolkit을 사용하고 있는데 정작 immer에 대해서 잘 모르는것 같아서 한번 공부해보려 한다.

Tookit의 장점

기존 Redux-saga는 사용하면서 정말 신세계를 경험하였으나, toolkit은 그보다 더 한 신세계를 경험하게 해주었다. CreateSlice를 통해 Action과 Reducer를 한번에 정의 할 수 있고, 자체적으로 immer도 깔려있어서 코드를 짧게 쓸수 있었다.
또한 비동기 처리도 CreateAsyncThunk 를 통해 thunk 미들웨어를 내장하고있어서 추가로 비동기 처리를 위한 외부 라이브러리도 필요 없다.


Redux-toolkit에 포함되는 것

  • configureStore() : 슬라이스 리듀서를 자동으로 결합하고 제공하는 Redux 미들웨어를 추가하고, 기본적으로 redux-thunk를 포함하며 Redux DevTools Extension을 사용할 수 있다.

  • createReducer() : switch 문을 작성하지 않고 reducer함수를 작성할 수 있다. 또한 immer를 사용하여 state.todos.completed = true와 같은 일반적인 코드로 더 간단하게 불변성을 유지하면서 상태를 업데이트할 수 있다.

  • createAction() : 주어진 action type에 따라 action create함수를 반환한다. 함수 자체에 toString()이 정의되어 있으므로 별도의 상수를 선언할 필요 없이 함수 이름을 사용할 수 있다.

  • createSlice() : 리듀서 함수 세트로서, 슬라이스 이름 및 초기 상태 값을 받아서 자동으로 slice reducer와 action creator, action types를 생성한다.


immer란?

immer란 간단하게 말하면 react에서 불변성을 유지하는 코드를 작성하기 쉽게 해주는 라이브러리이다.
toolkit에 기본적으로 깔려있어 추가적으로 설치해주지 않아도 된다.

불변성 : 상태를 변경하지 않는 것입니다.

react는 기본적으로 부모 컴포넌트가 리렌더링을 하면 자식 컴포넌트도 리렌더링하게 된다.
즉, 얕은 비교를 통해 새로운 값인지 아닌지를 판단한 후 새로운 값인 경우 리렌더링을 하게 된다.
여기서 얕은 비교란 간단히 말하자면 객체, 배열, 함수와 같은 참조 타입들을 실제 내부 값까지 비교하지 않고 동일 참조인지(동일한 메모리 값을 사용하는지)를 비교하는 것을 뜻한다.

예시의 시나리오를 보면서 왜 react에서 요소를 직접 변경하면 안되는지 알아보자.

  1. 우리가 컴포넌트를 리렌더링 해야하는 상황이 있다고 가정하고, 타입이 배열인 state를 바꾸었다.

  2. 이때, state.push(1)을 통해 state 배열에 직접 접근하여 요소를 추가한다.

  3. 우리는 push 전과 다른 값이라고 생각하지만, 리엑트는 state라는 값은 새로운 참조값이 아니기 때문에 이전과 같은 값이라고 인식하고 리렌더링 하지 않는다.

  4. 즉, 위 이유로 우리가 state를 바꾸고 돔을 다시 만들려면, 새로운 객체 or 배열을 만들어 새로운 참조값을 만들고, react에게 이 값은 이전과 다른 참조값임을 알려야하는 것입니다.

위 과정은 가상 dom에서만 이뤄지는 렌더링이며, 렌더링을 마치면 react의 비교 알고리즘에 의해 변화가 일어난 컴포넌트만 실제로 업데이트되어 우리 눈에 보이게 되는 것이죠.

배열 혹은 객체를 바꾸면서 불변성을 유지하면서 변경하는 방법이 있으나, immer.js를 이용하면 일반 객체 또는 배열을 다루듯 사용하면 immer가 불변성을 유지시켜준다.


produce

import produce from "immer";

const baseState = [
  {
    todo: "Learn typescript",
    done: true
  },
  {
    todo: "Try immer",
    done: false
  }
];

const nextState = produce(baseState, draftState => {
  draftState.push({ todo: "Tweet about it" });
  draftState[1].done = true;
});

immer에서 우리가 쓸 함수는 오직 produce만 알면 된다.
2가지의 파람을 가져오고 첫번째는 수정하고 싶은 객체/배열, 두번째는 첫번째 파라미터에 할당된 객체/배열을 바꾸는 함수입니다.

const baseState = [
  {
    todo: "Learn typescript",
    done: true
  },
  {
    todo: "Try immer",
    done: true
  },
  {
  	todo: "Tweet about it"
  }
];

공부를 하는데도 immer에 대해서 여전히 이해가 가지 않는다...

참고: 기억보다 기록을
https://kyounghwan01.github.io/blog/React/redux/redux-toolkit/#%E1%84%89%E1%85%A1%E1%84%8B%E1%85%AD%E1%86%BC%E1%84%92%E1%85%A1%E1%84%82%E1%85%B3%E1%86%AB-%E1%84%8B%E1%85%B5%E1%84%8B%E1%85%B2

0개의 댓글