^윗글을 참고하였다! 나도 언젠가 구글링했을 때 처음으로 나오는 유용한 글을 쓰는 개발 블로거가 되고 싶다..!!
1. 윗글을 읽어 보았는데 완벽하게 이해하려면 꽤나 시간이 걸릴 것 같아 우선 간단하게 정리하고, 추후 지속적으로 내용을 업그레이드할 예정이다.
2. 먼저 produce 함수의 내부를 뜯어보자.
export class Immer {
produce: (base, recipe) => {
let result;
const scope = enterScope(this);
const proxy = createProxy(this, base, undefined);
result = recipe(proxy);
return processResult(result, scope);
}
}
produce 는 매개변수로 base, recipe 를 받고 있다. 또 proxy 변수에 새로운 Proxy 를 만들어 저장하고, 그 proxy 를 recipe 함수에 전달해 결과를 만든 다음 result 와 scope 를 processResult 함수에 인자로 넣어 리턴한다.
앞서 살펴 보았듯, base 는 기존의 객체, recipe 는 업데이트 함수이다. scope 는 immer 전역에서 사용할 데이터를 저장하는 변수라고 간단히 알아두자.
중요한 것은 proxy 이다.
3. 그럼 createProxy 함수를 뜯어보자.
export function createProxy(immer, value, parent) {
const draft = createProxyProxy(value, parent);
const scope = getCurrentScope();
scope.drafts_.push(draft);
return draft;
}
앗 이런! createProxy 안에 createProxyProxy 라는 함수가 하나 더 있다! 이는 뒤에서 뜯어 보기로 하고, 중요한 건 scope.drafts_.push(draft) 이 부분이다. 생성한 proxy 들은 scope.drafts_ 배열에 push 된다.
4. 다음으로 createProxyProxy 함수를 뜯어보자.
export function createProxyProxy(base, parent) {
const state = {
...
scope_: getCurrentScope(),
modified_: false,
finalized_: false,
parent_: parent,
base_: base,
draft_: null,
copy_: null,
...
}
const target = state;
const traps = objectTraps
const { revoke, proxy } = Proxy.revocable(target, traps);
state.draft_ = proxy;
state.revoke_ = revoke
return proxy;
}
사실상 이 함수가 가장 근본(근_본)이 되는 함수라고 볼 수 있다. immer 를 사용하기 위해 필요한 메타데이터를 저장하고 있으며, 새로운 proxy 객체를 만들어 리턴하고 있기 때문이다.
base_: 기존 data. produce에서 첫번째 인자로 들어왔으며 변경되기 이전 원본 데이터를 여기에 저장한다.
copy_: 업데이트 된 data. 원본 데이터와 recipe를 이용해서 업데이트 된 데이터를 여기에 저장한다. 아직은 아무 데이터도 저장되어 있지 않다.
draft_: draft_ 는 여기서 생성되는 Proxy 객체를 저장한다. 앞으로의 로직에서 draft_.base_나 draft_.copy_와 같은 방법으로 데이터를 참조하게 된다.
modified_: 객체가 변경되었는지 여부를 저장한다. 기본 값은 객체가 변경되지 않았으므로 false 이다.
finalized_: proxy가 업데이트가 완료되어 return 될 준비가 되었는지를 저장한다. 기본 값은 객체가 준비 중이므로 false 이다.
parent_: 객체는 multi depth로 구성될 수 있다. 만약 객체가 트리 형태로 구성된다면 부모 객체를 이 곳에 저장하게 된다. root proxy에서는 부모가 없다.
메타 데이터 설명은 윗 블로그에 있는 설명으로 갈음한다! 너무 잘 정리해주신 관계로!
5. 이제 Proxy.revocable 과 traps 를 이용해 새로운 객체를 생성하는 방법만 정리하면 된다! 이는 내일 꼬꼬코 주제로 토스!
'꼬리에 꼬리를 무는 코딩' 카테고리의 다른 글
2022.10.05 꼬꼬코 왜 컴퓨터는 왜 바이트 단위로 동작하는가? 왜 1바이트는 8비트인가? (0) | 2022.10.06 |
---|---|
2022.10.04 꼬꼬코 (0) | 2022.10.05 |
2022.10.02 꼬꼬코 immer 라이브러리 심화 (0) | 2022.10.03 |
2022.10.01 꼬꼬코 immer 라이브러리 (0) | 2022.10.02 |
2022.09.30 꼬꼬코 react-virtualized 를 사용한 렌더링 최적화 (1) | 2022.09.30 |
댓글