이 글은 이 아티클을 따라 실습을 진행하며 작성한 글입니다.
이 전편의 내용은 링크를 통해 확인 해주세요!
전편에서는 리액트의 렌더 함수를 직접 구현하여 리액트를 사용하지 않고, 컴포넌트를 렌더링 하는 것 까지 구현을 했습니다.
전편에서 만든 yuact는 렌더링 재귀적으로 진행 하고 있는데, 커다란 돔을 한번에 렌더링 하게 될 경우 메인스레드를 너무 오래 차지하기 때문에, 이를 조금 수정해야 합니다.
따라서, 작업을 작은 단위로 나누고 각 작업이 끝난 후, 다른 할 일이 있다면 렌더링을 중단해야 합니다.
브라우저의 requestIdleCallback을 사용하면 브라우저가 유휴 상태 일때 콜백을 실행 할 수 있다.
let nextUnitOfWork = null;
function workLoop(deadline) {
let shouldYield = false;
while (nextUnitOfWork && !shouldYield) {
nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
shouldYield = deadline.timeRemaining() < 1;
}
requestIdleCallback(workLoop);
}
requestIdleCallback(workLoop);
function performUnitOfWork(nextUnitOfWork) {
// TODO
}
fiber 장에서는 렌더 트리를 fiber 구조로 만들기 위해 performUnit of work함수의 로직을 작성한다.
PerformUnitOfWork
function performUnitOfWork(fiber) {
// TODO add dom node
if (!fiber.dom) {
fiber.dom = createDom(fiber);
}
if (fiber.parent) {
fiber.parent.dom.appendChild(fiber.dom);
}
// TODO create new fibers
const elements = fiber.props.children;
let index = 0;
let prevSibling = null;
while (index < elements.length) {
const element = elements[index];
const newFiber = {
type: element.type,
props: element.props,
parent: fiber,
dom: null,
};
// TODO return next unit of work
if (index === 0) {
fiber.child = newFiber;
} else {
prevSibling.sibling = newFiber;
}
prevSibling = newFiber;
index++;
}
if (fiber.child) {
return fiber.child;
}
let nextFiber = fiber;
while (nextFiber) {
if (nextFiber.sibling) {
return nextFiber.sibling;
}
nextFiber = nextFiber.parent;
}
}
--- 만들다 보니까 뭔가 리액트 앱 만들 때, jsx의 트리 구조를 어떤식으로 짜야할 지 감이 잡히는 것 같기도 하고,,---
'프로그래밍 > frontend.' 카테고리의 다른 글
Turborepo를 사용하여 모노레포 구성하기: Storybook 포함 (0) | 2024.10.31 |
---|---|
리액트 따라만들기 2편. createElement 함수 구현하기 (0) | 2022.04.25 |
리액트 따라 만들기 1편. (0) | 2022.04.25 |
ssr! (0) | 2022.04.19 |
visual studio code에서 prettier 설정값을 공유 합니다. (0) | 2022.04.02 |