본문으로 건너뛰기

"redux" 태그로 연결된 2개 게시물개의 게시물이 있습니다.

모든 태그 보기

immer 내부 살펴보기

· 약 45분
Hyunmo Ahn
Front End Engineer @ Line+

이 글은 기본적으로 immer에 대해서 알아보는 시간을 가진다. 만약 immer를 잘 모르는 분들은 아래 챕터를 먼저 읽어보는 것을 권장한다.

무엇이 궁금할까?

Question

Q1. immer는 객체 mutable하게 바꾸는 방식을 어떻게 immutable한 방식으로 바꾸어주고 있을까?

immer는 mutable하게 변경하는 객체 built-in method를 사용하더라도 immutable하게 데이터를 반환해주는 기능을 한다. 이 기능이 내부적으로 어떤 방식으로 이루어지는지 알아본다.

아래 코드 예시는 immer 공식 문서에 존재하는 basic example을 가져온 것이다.

import produce from 'immer';

const baseState = [
{
title: "Learn TypeScript",
done: true,
},
{
title: "Try Immer",
done: false,
},
]

const nextState = produce(baseState, (draft) => {
draft.push({ title: "Tweet about It" });
draft[1].done = true;
})

console.log(baseState === nextState) // false
console.log(nextState)
/*
[
{
title: "Learn TypeScript",
done: true,
},
{
title: "Learn TypeScript",
done: true,
},
{
title: "Tweet about It",
},
]
*/
Question

Q2. immer는 어떻게 structural sharing을 사용하는걸까?

*structural sharing: 객체를 copy할 때 변경되지 않은 객체는 reference를 동일하게 사용하는 방식.

객체를 immutable하게 업데이트 한다는 것은 기존 객체를 새로운 객체로 복사한다는 것이다. 즉, 복사에 비용이 발생한다. immer는 객체를 복사할 때, 변경되지 않은 reference는 재사용하는 structural sharing 방식을 사용해서 객체를 복사한다. immer에서는 어떤방식을 사용해서 structural sharing을 사용하고 있는지 알아본다.

Question

Q3. immer에서는 produce함수 내에서 draft를 직접 업데이트하는 방식이 아니라 return을 통해서 데이터를 업데이트하는 경우가 있는데, 이런 경우에 로직이 다른지?

immer를 사용할 때, 위에서 제시한 mutable한 객체 변경 방식이 아닌, 새로운 객체를 리턴하는 경우가 있다. 이는 immer와는 무관하게 immutable하게 Javascript에서 객체를 반환해주는 방식과 동일하다. immer에서는 이러한 방식을 공식적으로 허용하고 있고 두 방식, mutable하게 객체를 변경하는 방식과 immutable하게 객체를 변경시키는 방식 모두 혼용해서 쓰는 개발자도 많을 것 이다. 이러한 방식 차이는 immer에서 어떤 로직차이를 발생시키는지 알아본다.

// mutable method
const nextState = produce(baseState, (draft) => {
draft.push({ title: "Tweet about It" });
draft[1].done = true;
})

// immutable method
const nextState = produce(baseState, (draft) => {
return {
...baseState,
{ ...baseState[1], done: true },
{ title: "Tweet about It" },
}
})
사전지식
  • immer 혹은 redux-toolkit을 사용해 본 경험
  • Proxy에 대한 이해 (optional)

redux-devtools의 time-travel-debugging 톺아보기

· 약 42분
Hyunmo Ahn
Front End Engineer @ Line+

목적

redux를 이용해서 웹 어플리케이션 개발을 진행해 본 사람이라면 redux-devtools를 이용해서 time-travel 디버깅을 사용해본 경험이 있을 것이다.

redux-devtools가 어떤 것인지 헷갈리시는 분이 있다면 아래 영상을 참고하기 바란다.

만약 redux-devtools를 사용해 본 경험이 없다면 이번 article을 이해하기 어려울 수 있다.

redux-devtools는 redux를 사용한 web application의 redux정보(action, reducer, state)를 기록하고, 특정 시점의 reducer로 rollback하고, 특정 action을 없었던 일로 할 수 있다. 하지만, redux-devtools를 사용하지 않고 web application 내부에 비슷한 동작을 구현을 하려 한다면 간단한 일이 아니다. 예를들어, A버튼을 눌렀을 때 이제껏 발생시켰던 action을 없었던 일로 한다거나, Submit버튼을 누르기 전 이탈 한다면 해당 페이지에서 발생시켰던 모든 action을 rollback한다거나 하는 로직말이다.

redux-devtools는 버튼으로 손쉽게 제공하는 동작을 직접 로직을 구현한다고 하면 방법을 모르겠다. redux-devtools는 어떻게 이러한 일들을 가능하게 할까?

이 article에서는

  • redux-devtools 에서 호출되는 action과 reducer를 logging하는 방법.
  • redux-devtools 에서 특정 action이 dispatch 된 시점으로 jump하는 방법.
  • redux-devtools 에서 특정 action이 동작하지 않은 것 처럼 skip시키는 방법.

에 대해서 확인해 볼 것 이다.

사전지식
Caution
  • 이 문서는 browser extension에 대한 내용은 다루지 않습니다.
  • redux-devtools의 core에 대해서 다루고 있으며 browser extension에 대한 지식이 없어도 이해가 가능합니다.
  • redux-devtools-extensions와 관련하여 browser extension에 대한 내용을 원하는 분들은 이 글에서 다루는 내용과 맞지 않을 수 있습니다.