패캠 인강/React

React 기초 다지기 (1) - JSX 기초

Je-chan 2022. 1. 6. 19:46

1. React 로 DOM 렌더링하기

<!DOCTYPE html>
<html lang="en">
  <body>
    <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>
    <div id="root"></div>
    <script>
      const rootElement = document.getElementById("root");
      // vanilla javascript 로 구현하는 내용
      // const element = document.createElement("h1");
      // element.textContent = "Vanilla Javascript: Hello World!";
      const element = React.createElement(
        "h1",
        {
          className: "title",
          children: "Hello???"
        },
        ["React: Hello World", "It's me!"]
      );

      console.log(element);
      // 객체를 리턴한다.
      // $$typeof: Symbol(react.element)
      // key: null
      // props: {children: 'React: Hello World!'}
      // ref: null
      // type: "h1"
      // _owner: null
      // _store: {validated: false}
      // _self: null
      // _source: null

      // rootElement.appendChild(element);
      ReactDOM.render(element, rootElement);
    </script>
  </body>
</html>

 

2. JSX 활용하기

  JSX 란? 문자도, HTML 도 아닌 자바스크립트의 확장 문법이다. 밑의 예제에서는 element 변수가 JSX 를 활용한 것이다. 그러나 일반 자바스크립트에서 JSX 문법을 사용할 수 없다. JSX 를 자바스크립트로 해석하기 위해서 자바스크립트 컴파일러로 Babel을 사용한다.  위의 내용은 아래와 같이 표현할 수 있다. Babel 은 script 태그에 CDN 을 이용해서 가져왔다.

<!DOCTYPE html>
<html lang="en">
  <body>
    <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>
    <div id="root"></div>
    <script type="text/babel">
      const rootElement = document.getElementById("root");
      const text = "React: Hello World";
      // JSX 에서 자바스크립트 문법(변수, 함수 등)을 쓰고 싶을 때는 {} 로 감싼다
      const element = <h1 className="title">{text}</h1>;
      ReactDOM.render(element, rootElement);
    </script>
  </body>
</html>

 

  이번에는 여러 태그들을 만들어서 넣어보도록 하자. 태그를 넣을 때 좋은 방법 중 하나는 React 가 반환하는 객체에서 children 을 이용하는 것이다. children 이 하위 태그들을 의미하기 때문. React JSX 문법에는 여러 Element 들을 사용할 때 반드시 그것을 묶는 하나의 태그가 존재해야 한다. 그러나, 만약 그 태그를 추가적으로 사용하는 것이 싫다면 React.Fragment 를 이용해서 묶어줄 수 있다. 

 

<!DOCTYPE html>
<html lang="en">
  <body>
    <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>
    <div id="root"></div>
    <script type="text/babel">
      const rootElement = document.getElementById("root");
      const title = "React: Hello World";
      const subTitle = "It is JSX";
      const element = (
        // 아래와 같이 작성하게 되면 오직 여러 태그를 묶어주기 위한 의미없는 div 태그가 발생하게 된다
        // 이렇게 작성하는 것이 싫기에 React.Fragment 가 나왔다.
        // HTML 구조로 비교해보면 바로 아래 주석처리된 부분은 div 태그 안에 h1, h2 태그가 존재하는 것이 되지만
        // React.Fragment 에서는 h1, h2 태그만 부모 태그 없이 형제 태그로 존재한다. 
        // 즉, React.Fragment 는 렌더링되지 않는 태그
        // <div
        //   className="titleBox"
        //   children={[
        //     React.createElement("h1", null, title),
        //     React.createElement("h2", null, subTitle)
        //   ]}
        // ></div>

        // 이렇게 React.createElement 로 쓸 수 있고
        // <React.Fragment
        //   className="titleBox"
        //   children={[
        //     React.createElement("h1", null, title),
        //     React.createElement("h2", null, subTitle)
        //   ]}
        // />

        // JSX 문법으로도 쓸 수 있다.
        // JSX 에서 Fragment 는 <></> 
        <>
          <h1>{title}</h1>
          <h2>{subTitle}</h2>
        </>
      );
      ReactDOM.render(element, rootElement);
    </script>
  </body>
</html>

 

  Element 를 찍는 또 다른 방법으로 기존 자바스크립트에서는 function 으로 DOM 조작하는 방법이 있었다. 하지만, React 에서 함수가 있을 때 첫 번째 인자는 타입, 두 번째 인자는 props, 세 번째 인자는 children 이었다. 거기에서 props (객체) 값을 줌으로써 개발자가Customizing 한 Element 를 찍어낼 수 있다. 이렇게 만들어 내는 JSX 기반의 Element 는 기존 html 태그와 혼동을 줄 수 있으므로 반드시 대문자로 먼저 시작한다. 

 

<!DOCTYPE html>
<html lang="en">
  <body>
    <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>
    <div id="root"></div>
    <script type="text/babel">
      const rootElement = document.getElementById("root");
	
      // 아래 주석의 내용이 기존 function 으로 Element 를 만들어내는 방식
      // const theme = (title, subTitle) => (
      //   <>
      //     <h1>{title}</h1>
      //     <h2>{subTitle}</h2>
      //   </>
      // );

      // const element = (
      //   <>
      //     {theme("React", "JSX")}
      //     {theme("rEACT", "jsx")}
      //   </>
      // );

	  // 밑에 있는 방식이 JSX 기반의 Element 를 만들어내는 방식
      
      const Theme = ({ title, subTitle }) => (
        <>
          <h1>{title}</h1>
          <h2>{subTitle}</h2>
        </>
      );

      const element = (
        <>
          <Theme title="React" subTitle="JSX" />
          <Theme title="rEACT" subTitle="jsx"></Theme>
        </>
      );

      ReactDOM.render(element, rootElement);
    </script>
  </body>
</html>

 

  JSX 는 자바스크립트 확장 문법이다. 즉, 자바스크립트 문법 (if, for 문 등) 을 사용할 수 있다는 얘기다. 

 

<!DOCTYPE html>
<html lang="en">
  <body>
    <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>
    <div id="root"></div>
    <script type="text/babel">
      const rootElement = document.getElementById("root");

      const Theme = ({ title, subTitle }) => {
        if (title.charAt(0) === title.charAt(0).toLowerCase()) {
          return (
            <>
              <h1>{title.toLowerCase()}</h1>
              <h2>{subTitle}</h2>
            </>
          );
        } else {
          return (
            <>
              <h1>{title}</h1>
              <h2>{subTitle}</h2>
            </>
          );
        }
      };

      const element = (
        <>
          <Theme title="React" subTitle="JSX" />
          <Theme title="rEACT" subTitle="jsx"></Theme>
        </>
      );

      ReactDOM.render(element, rootElement);
    </script>
  </body>
</html>