본문 바로가기

프로그래밍/frontend.

리액트 따라만들기 2편. createElement 함수 구현하기

전편: https://kiwitrip.tistory.com/entry/리액트-따라-만들기-1편

github: https://github.com/leeyh-kor/make_react

 

TODO:

  • react의 create element 함수를 구현한다.
  • createTextElement 함수를 구현한다.
  • 두 함수를 오브젝트로 묶어서 사용 가능하게 구현한다.
  • 오직 show만 가능한 render 함수 구현 (업데이트 및 삭제는 나중에 구현)

createElement함수

createElement 함수는 element 트리를 반환한다. 

element 의 자식 요소들이 text(string or number)일 경우 textElement를 반환하고, 아닐 경우 오브젝트를 그대로 반환한다.

function createElement(type, props, ...children) {
  return {
    type,
    props: {
      ...props,
      children: children.map((child) =>
        typeof child === "object" ? child : createTextElement(child)
      ),
    },
  };
}

//use case

createElement("div", null, a)
/**
   {
    "type": "div",
    "props": { "children": [a] }
  } 
 */
createElement("div", null, a, b) 
/**
   {
    "type": "div",
    "props": { "children": [a, b] }
  } 
 */

createTextElement함수

function createTextElement(text) {
  return {
    type: "TEXT_ELEMENT",
    props: {
      nodeValue: text,
      children: [],
    },
  };
}

render 함수 만들기

function render(element, container) {
  const dom =
    element.type === "TEXT_ELEMENT"
      ? document.createTextNode("")
      : document.createElement(element.type);

  const isProperty = (key) => key !== "children";

  Object.keys(element.props)
    .filter(isProperty)
    .forEach((name) => {
      dom[name] = element.props[name];
    });

  element.props.children.forEach((child) => {
    return render(child, dom);
  });
  container.appendChild(dom);
}

만든 함수들을 Yuact 모듈로 만들기

const Yuact = {
  createElement,
};

 

babel이 Yuact를 사용하도록 설정하기

jsx컴포넌트를 react 컴포넌트로 바꾸기 위해서는 babel을 사용 해야 하는데, babel create react app을 통해서 react 앱을 만들게 되먄, babel은 기본적으로 react의 create element를 사용하기 때문에 이를 Yuact로 바꿔줘야 함.

/** Yuact.createElement */
const element = (
  <div id="foo">
    <a>bar</a>
    <b />
  </div>
);