바닐라 자바스크립트로 직접 리액트의 주요 기능을 만들어보며, 동작원리를 좀더 심층적으로 이해하기 위해 아래 글을 따라가며 얻은 인사이트와 학습을 기록하는 글입니다. 또한 아래 글의 4가지 챕터로 리액트의 동작원리를 이해하는 단계를 그대로 따라가기에, 아래 Medium 글을 참고하시는게 직접 해보시는 것에는 도움이 되실 겁니다.
lets-build-a-react-from-scratch-part-3-react-suspense-and-concurrent-mode
git hub repo : part3 branch(파트에 따라서 브랜치를 분배 했습니다)
위의 글에서는 문제점에 대해 이야기 하고, 해결은 작은 과제처럼 남겨두었길래, 이 글에 문제점에 대한 해결의 내용을 남겨보려고 한다.
export const resourceCache = {};
const createResource = (fallback,task, key, ) => {
//리소스 캐시가 있으면 참조하고, 없으면 propmise,key,fallback 을 throw 한다.
if (resourceCache[key]) return resourceCache[key];
const promise = asyncTask();
throw { promise, key, fallback };
};
export const Suspense = (props, children) => {
const { fallback, task, key } = props;
createResource(fallback,task,key);
return children;
};
//app.tsx
export default function App () {
...
const photo1 = resourceCache["photo1"];
const photo2 = resourceCache["photo2"];
...
//비동기 적으로 불러오는 리소스를 참조하는 컴포넌트를 Suspense 컴포넌트로 감싼다.
<Suspense
fallback={<h2>사진1 로딩중...</h2>}
task={() => getMyAwesomePic("photo1")}
key={"photo1"}
>
<img src={photo1} alt="사진1" />
</Suspense>
<Suspense
fallback={<h2>사진2 로딩중...</h2>}
task={() => getMyAwesomePic("photo2")}
key={"photo2"}
>
<img src={photo2} alt="사진2" />
</Suspense>
...
//React.createElement 수정
const React = {
createElement: (tag, props, ...children) => {
if (typeof tag === "function") {
try {
return tag(props, ...children);
} catch ({ promise, key, fallback }) {
promise.then((value) => {
resourceCache[key] = value;
reRender();
});
return fallback;
}
}
const el = {
tag,
props,
children,
};
return el;
},
};
export default React;

위 글의 문제점 처럼 task 1을 해결한 후에 task2를 실행하는 것이 아니라, task1,task2가 해결되면 fallbackUI 가아닌 실제 렌더링 해야하는 요소를 각각 보여준다.