본문 바로가기

React/실험실

[React] 나만의 리액트 만들기 - 2 - 컴포넌트

Components와 Props 

이제 Components에 대해서 설명을 시작한다. 

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

제일 먼저 컴포넌트의 이해를 돕기 위해서 다음과 같은 함수가 나왔다. 

데이터를 가진 Props 객체를 받아서 React 엘리먼트를 반환하는 React 컴포넌트이다. 

 

함수 형태로 만들어져있기 때문에 " 함수 컴포넌트 "라고 불린다. 

 

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

const root = ReactDOM.createRoot(document.getElementById('root'));
const element = <Welcome name="Sara" />;
root.render(element);

컴포넌트를 사용해서 화면에 렌더링이 가능하다. 

여기까지는 우리가 만든 Crazy React도 어떻게든 가능하다. 하지만 중첩이 된다면 어떨까? 

 

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

function App() {
  return (
    <div>
      <Welcome name="Sara" />
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  );
}

이게 우리가 원하는 최종 형태의 React이다. 

하지만 우리는 JSX가 아니기 때문에 함수 컴포넌트를 태그로 만들 수 없다. 

 

오늘은 이론부분을 짧게 가자.

어떻게하면 우리가 만든 함수형 컴포넌트를 중첩해서 사용하게 할 수 있을까? 

function Element() {
  const test = () => {};

  return `<div>
            <span onClick2={test} onClick='{() => test()}'>test2</span>
            <span>test<span>
          </div>
        `;
}

function App() {
  return `
      <div>
        <Element />
        <Element />
        <Element />
      </div>
    `;
}

export default App;

이게 우리가 원하는 형식인데 일단 태그 형식으로 만드는 것은 불가능할 것 같다. 

JSX가 아니기 때문에 태그를 인식하기에는 불가능 하다. 그럼 어떤 방법이 있을까?

 

let domParser = new DOMParser();

const CrazyReactDOM = (function () {
  let rootDom;

  return {
    createRoot(targetNode) {
      rootDom = targetNode;

      return this;
    },

    render(node) {
      rootDom.innerHTML = node.render();
    },

    createNode(Component) {
      return {
        //
        element: null,
        render: function (props) {
          const rowElement = Component(props);
          const elementChildren = domParser
            .parseFromString(rowElement, "text/html")
            .querySelector("body").children;

          if (elementChildren.length !== 1) return;

          this.element = elementChildren[0];

          return this.element.outerHTML;
        },
      };
    },
  };
})();

export default CrazyReactDOM;

CrazyReactDOM을 조금 변경 시켜봤다. 

 

createNode라는 함수를 만들어서 내부에서 element를 관리하는 형식으로 만들었다. 

추후 이벤트를 준다던지 할 경우 element를 직접 컨트롤할 수 있어야하는데,

그럼 객체를 return 하는 방법말고는 당장 생각나는 형식이 없다. 

 

당연히 현재 만든 함수가 최종까지 남아있을지는 미지수이다. 

하지만 React에 맞는 형식으로 변경을 시켜가면 언젠간 모든 기능을 만들 수 있지 않을까 생각이든다.

 

조금씩 천천히 모든 기능을 추가해보자

 

참고

https://ko.reactjs.org/docs/components-and-props.html

 

Components와 Props – React

A JavaScript library for building user interfaces

ko.reactjs.org

 

깃허브

https://github.com/SeoJaeWan/Crazy-React/pull/2

 

feature: 컴포넌트 구현 by SeoJaeWan · Pull Request #2 · SeoJaeWan/Crazy-React

2일차 - 22/09/28 어떻게하면 함수형 컴포넌트의 방식으로 각 컴포넌트를 부모 컴포넌트에 렌더링 시킬지 고민하다가 구현을 하였다. 어제의 함수 부분과 마찬가지로 현재 구현 상태로 과연 리렌

github.com

 

반응형