JSX

</>·2021년 10월 10일
6

Get to Know React

목록 보기
1/8
post-thumbnail
post-custom-banner

목표

  • Vanilla js에서 React로 자연스럽게 넘어가는 방법을 알아본다.
  • JSX 문법에 대해 알아본다.

1. Vanilla javascript

1-1. element 생성하기

<!DOCTYPE html>
<html lang="ko">
  <body>
    <div id="root"></div>
    <script>
      const rootElement = document.getElementById("root");
      const element = document.createElement("h1");
      element.textContent = "Hello, World";
      rootElement.appendChild(element);
    </script>
  </body>
</html>

2. React

2-1. CDN(Content Delivery Network)이란?

  • 리액트 프레임워크를 사용하는 방법 중 하나는 CDN을 script 태그에 넣고 사용하는 것이다.

CDN 이란?

  • 웹에서 사용되는 다양한 컨텐츠(리소스)를 저장하요 제공하는 시스템을 말한다.

2-2. element 생성하기

<!DOCTYPE html>
<html lang="ko">
  <head>
    <script
      crossorigin
      src="https://unpkg.com/react@17/umd/react.development.js"
    ></script>
    <script
      crossorigin
      src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"
    ></script>
  </head>
  <body>
    <div id="root"></div>
    <script>
      const rootElement = document.getElementById("root");
      // const element = React.createElement("h1", { children: "Hello, world" });
      const element = React.createElement("h1", null, "Hello World");
      ReactDOM.render(element, rootElement);
    </script>
  </body>
</html>
  • 인자에 따라 엘리먼트를 생성하는 createElement 함수는 React 공식 문서에서 확인할 수 있다.
React.createElement(
  type,
  [props],
  [...children]
)
  • 또한, 엘리먼트를 DOM에 렌더링 하고 싶을 때에는 render 함수를 사용하는데, 이 또한 React 공식 문서에서 확인할 수 있다.

DOM(Document Object Model) 이란?

  • 메모리에 웹 페이지 문서 구조를 표현함으로써 스크립트 및 프로그래밍 언어와 페이지를 연결한다.
  • DOM은 문서를 논리 트리로 표현한다.
  • 이를 통해 문서의 구조, 스타일, 콘텐츠를 변경할 수 있다.
  • 즉, Element는 우리 눈에 보여지는 것이고 DOM은 컴퓨터(브라우저)가 이해하는 엘리멘트의 원형이라고 생 각할 수 있다.

 


3. JSX

🤔 의문

  1. 바닐라 js로 엘리멘트를 생성하는 것과 React의 createElement로 엘리멘트를 생성 하는 것은 별 차이 없어 보였고 굳이 사용하는 이유를 모르겠다.
  2. 둘 다 엘리먼트를 많이 만들어야 할 때 처럼 createElement 함수를 일일히 다 선언해주는 것은 너무 비효율적이라는 생각이 들었다.

그래서 나온 것인 JSX이다.

3-1. JSX란?

  • 문자도 HTML도 아닌 자바스크립트의 확장 문법이다.
const element = <h3>Hello, World</h3>
  • 자바스크립트가 이 JSX 문법을 사용하기 위해서는 바벨(babel)이란 것이 필요하다. 바벨의 상세한 내용은 바벨 공식 문서에서 확인할 수 있다.

바벨(babel)이란?

  1. 자바스크립트 컴파일러이다.
  2. 컴파일러는 언어 해석기로 특정 언어를 다른 프로그래밍 언어로 옮기는 프로그램을 뜻한다.
  • 즉, 위 코드를 아래와 같이 컴파일 해주는 역할을 한다.
// const element = <h3 className="hello">Hello, World</h3>

"use strict";

const element = /*#__PURE__*/React.createElement("h3", {
  className: "hello"
}, "Hello, World");
  • 바벨 역시 CDN을 통해 사용할 수 있는데 이 역시 바벨 공식 문서에서 확인할 수 있다.
<!DOCTYPE html>
<html lang="ko">
  <head>
    <script
      crossorigin
      src="https://unpkg.com/react@17/umd/react.development.js"
    ></script>
    <script
      crossorigin
      src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"
    ></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  </head>
  <body>
    <div id="root"></div>
    <script type="text/babel">
      const rootElement = document.getElementById("root");
      const element = <h1 className="hello">hello, world</h1>;
      ReactDOM.render(element, rootElement);
    </script>
  </body>
</html>

💡 주의

  • 자바스크립트가 이해하는 script와 바벨이 이해하는 script가 다르기 때문에 위의 코드 처럼 script 태그 안에 type="text/babel"을 넣어 주어야 한다.

3-2. JSX 응용하기

  • 문자열과 클래스네임을 따로 변수로 선언하여 넣을 수도 있다.
  <body>
    <div id="root"></div>
    <script type="text/babel">
      const rootElement = document.getElementById("root");
      const text = "hello, world";
      const className = "hello";
      const element = <h1 className={className}>{text}</h1>;
      ReactDOM.render(element, rootElement);
    </script>
  </body>

4. 멀티 Element 생성하기

4-1. Vanilla javascript

  <body>
    <div id="root">
      <h1>First child</h1>
      <h2>second child</h2>
      <h3>third child</h3>
    </div>
  </body>
  • id가 root인 div 태그 안에 3개의 엘리멘트를 생성했다.

4-2. React

  <body>
    <div id="root"></div>
    <script type="text/babel">
      const rootElement = document.getElementById("root");
      const element = (
        <div
          className="children"
          children={[
            React.createElement("h1", null, "First child"),
            React.createElement("h2", null, "Second child"),
            React.createElement("h3", null, "Third child")
          ]}
        />
      );
      ReactDOM.render(element, rootElement);
    </script>
  </body>
  • id가 root인 div 태그 안에 3개의 엘리먼트를 감싸기 위한 부모 div 태그와 3개의 엘리멘트를 생성했다.

🤔 의문

  • 바닐라 js로 엘리멘트를 생성할 때에는 root div 태그에 생성되었는데 React로 엘리멘트를 생성할 때에는 필요없는 div 태그를 하나 더 생성했는데 비효율 적이다.

그래서 리액트에서 Flagment라는 것을 만들었다.

4-3. Flagment

  • 위의 비효율 적인 상황을 방지하기 위해 React는 부모로써 감싸주는 역할만 하는 Flagment를 제공한다.
      const element = (
        <React.Fragment
          className="children"
          children={[
            React.createElement("h1", null, "First child"),
            React.createElement("h2", null, "Second child"),
            React.createElement("h3", null, "Third child")
          ]}
        />
      );
  • JSX 문법을 사용해서 Flagment를 다르게 표현할 수 있다. JSX 문법을 사용하면 코드가 훨씬 깔끔해지는 것을 확인할 수 있다.
      const element = (
        <>
          <h1>First child</h1>
          <h2>Second child</h2>
          <h3>Third child</h3>
        </>
      );

5. Element 찍어내기

5-1. javscript + react

      const print = (number, gender) => (
        <>
          <h1>{number} child</h1>
          <h2>{gender}</h2>
        </>
      );

      const element = (
        <>
          {print("First", "man")}
          {print("Second", "woman")}
          {print("Third", "man")}
        </>
      );
  • 바뀌는 값들을 함수의 인자로 주어 여러 Element를 찍어낼 수 있다.

5-2. JSX

     const Print = ({ number, gender }) => {
        return (
          <>
            <h1>{number} child</h1>
            <h2>{gender}</h2>
          </>
        );
      };

      const element = (
        <>
          <Print number="First" gender="man" />
          <Print number="Second" gender="woman" />
          <Print number="Third" gender="man" />
        </>
      );
  • JSX 문법을 쓰면 커스텀 엘리먼트를 만들 수 있다.
  • 위의 코드에서는 Print 엘리먼트에서 함수로 Props 객체를 넘겨주어 각 엘리멘트 마다 다른 number과 gender값을 사용해 다르게 찍어냈다.

💡 주의

  • JSX 문법을 사용해 엘리먼트를 생성할 때에는 무조건 첫 글자를 대문자로 시작하여야 한다. 소문자를 사용하게 되면 기존 html 태그들과 혼동이 발생할 수 있기 때문에 명시적으로 React에서 만들어 놓은 규칙이다.
  • 실제로 아래와 같은 에러가 발생한다.

5-3. children 이용하기

    const Print = ({ number, gender, children }) => {
      return (
        <>
          <h1>{number} child</h1>
          <h2>{gender}</h2>
          {children}
        </>
      );
    };

    const element = (
      <>
        <Print number="First" gender="man">
          <h3>My name is Biber</h3>
        </Print>
        <Print number="Second" gender="woman" />
        <Print number="Third" gender="man" />
      </>
    );
  • Print 엘리먼트에 children인 h3태그를 감싸주어 전달하면 h3 태그 내용도 잘 찍히는 것을 볼 수 있다. 이는 엘리먼트를 확장할 수 있는데 굉장히 용이하다.

6. Javascript와 JSX 함께 쓰기

6-1. 분기문

  • 분기문(if문)을 이용해서 엘리먼트를 다르게 출력할 수 있다.
  • 다음 코드는 첫글자가 대문자이면 h1 엘리먼트를 소문자이면 h2 엘리먼트를 리턴하는 코드이다.
      const Text = ({ text }) => {
        if (text.charAt(0) === text.charAt(0).toUpperCase()) {
          return <h1>{text}</h1>;
        } else {
          return <h2>{text}</h2>;
        }
      };

      const element = (
        <>
          <Text text="UpperCase" />
          <Text text="lowercase" />
        </>
      );
  • 또는 삼항 연산자를 통해 엘리먼트를 리턴할 수 있다.
      const Text = ({ text }) => {
        return text.charAt(0) === text.charAt(0).toUpperCase() ? (
          <h1>{text}</h1>
        ) : (
          <h2>{text}</h2>
        );
      };

6-2. 반복문

  • 반복문을 이용해서 엘리먼트를 다르게 출력할 수 있다.
  • 다음 코드는 Props로 넘겨받은 number가 홀수이면 h1 엘리먼트를 짝수이면 h2 엘리먼트를 리턴하는 코드이다.
    const Number = ({ number }) => {
      return number % 2 !== 0 ? <h1>{number}</h1> : <h2>{number}</h2>;
    };

    const numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

    const element = (
      <>
        {numberArray.map((number) => (
          <Number key={number} number={number} />
        ))}
      </>
    );

참고

profile
개발자가 되고 싶은 개발자
post-custom-banner

0개의 댓글