React

[02] JSX 구문 이해하기

BGK97 2024. 4. 12. 14:51
    npx create-react-app (프로젝트 이름) --template typescript //타입스크립트 파일 생성
  • 이후 기존에 만들었던 src/data, prettier를 복사한다
    cp -r ../(폴더)/src/data ./src/data 
    cp -r ../(폴더)/.*. 

React.createElement의 호출의 복잡성 문제

React.createElement란

  • 가상 DOM객체를 만들어주는 함수
  • HTML 요소가 부모/자식 관계로 구성되면 코드가 복잡해지는 문제가 있음
  • 이를 해결하기 위해 JSX 기능을 언어 확장 형태로 추가

React vs JSX

React

// const rootVirtualDOM = CE("ul", null, [
//   CE("li", null, [
//     CE("a", { href: "http://www.google.com", target: "_blank" }, [
//       CE("p", null, "go to google"),
//     ]),
//   ]),
// ]);

JSX

const rootVirtualDOM = (
    <ul>
        <li>
            <a href="http://www.google.com" target="_blank">
                <p> go to Google </p>
            </a>
        </li>
    </ul>
)

....이하 동일

JSX

JS와 XML 의 합성

  • XML 구문에 자바스크립트 코드를 결합하는 용도로 사용
  • createElement 메서드를 여러번 호출하는 것 보다 JSX만 간결하게 사용하면 됨
  • 개발 생산성이 크게 향상

XML 용어 알아보기

  • <> 태그를 시작으로 끝 태그</>를 필수적으로 붙여야 함
  • 속성 값은 항상 ' ' 혹은 " "로 감싸주어야 함
  • 또한 자식 요소를 삽입할 수 있음
  • 문자열일 때는 ' ' 생략 가능
  • 자식 요소가 없을 때는 처럼 스스로 닫는 태그를 사용할 수 있음

XML(혹은 HTML5) 표준 준수

  • 리액트에서 JSX 구문 분석기는 웹 브라우저와는 전혀 무관
  • HTML 구문 분석기는 HTML4 등 하위 호환성을 보장하여 XML 규정에 어느정도 어긋나도 됨
  • 그러나 JSX 구문 작성시에는 XML 규약을 엄격하게 준수해야 함
    • 닫는 태그 등

JSX 구문에서 중괄호의 의미

  • 자바 스크립트 코드를 삽입할 때 사용하는 것
  • 그러나 표현식이기 때문에 반드시 return 없이 사용해야 함

표현식, 실행문, 그리고 JSX

  • 표현식
    • return 키워드 없이 어떤 값을 반환하는 코드
    • 값으로 평가되는 어떤 것
  • 실행문
    • 표현식과 대비되는 개념으로, 그 자체로는 값이 아님
    • for, if, switch~case 등...
  • console.log 호출은 가상DOM 객체를 반환하지 않는 실행문이기 때문에 가상 DOM 값을 넣을 수 없음
  • React.createElement 호출 코드로 변환할 수 없는 호출들은 전부다 오류가 발생함

배열과 JSX 구문

  • JSX 구문의 목적
    • React.createElement 호출을 간결하게 하기 위함
    • 이 때의 반환 값은 가상 DOM 객체 (그래서 createElement로 물리 DOM으로 변환하는 것)
  • 이 코드를 실행한 후에 개발 도구창을 보면 실제로 물리 DOM이 형성이 된 것을 확인할 수 있음
  • JSX는 React.createElement의 호출이므로 변수에 담기도 가능하며, 여러개 담기도 가능하다.
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";

// const CE = React.createElement;

// const rootVirtualDOM = CE("ul", null, [
//   CE("li", null, [
//     CE("a", { href: "http://www.google.com", target: "_blank" }, [
//       CE("p", null, "go to google"),
//     ]),
//   ]),
// ]);

// const root = ReactDOM.createRoot(
//   document.getElementById("root") as HTMLElement
// );
// root.render(rootVirtualDOM);

const child = [
  <li>
    <a href="http://www.google.com" target="_blank">
      <p>go to Google</p>
    </a>
  </li>,
  <li>
    <a href="http://www.facebook.com" target="_blank">
      <p>go to FaceBook</p>
    </a>
  </li>,
  <li>
    <a href="http://www.twitter.com" target="_blank">
      <p>go to Twitter</p>
    </a>
  </li>,
];

const rootVirtualDOM = <ul>{child}</ul>;
const root = ReactDOM.createRoot(
  document.getElementById("root") as HTMLElement
);
root.render(rootVirtualDOM);​

배열을 JSX문으로 만들 때 주의 사항

  • XML 작성 원칙 준수
  • XML 문법에서 XML 요소는 부모 없이 존재하지 못하기 때문에, 컴포넌트를 여러개 담은 배열이 있다면 부모 컴포넌트 없이는 절대로 {} 표현식을 사용할 수 없음
  • 위 코드에서 ul 태그를 삭제하면 오류가 날 것임

데이터 배열을 컴포넌트 배열로 만들기

  • map을 활용하여 화면에 출력시 HTML 상으로는 정상적으로 보이나 Console 메세지에는 key 속성값이 없다고 뜸
  • 가짜 데이터 배열 렌더링 하기

  • 데이터 유틸리티 함수로 요소 만들기

결과화면

 

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import * as D from "./data";

const child = D.makeArray(10).map((notUsed, index) => (
  <div key={index}>
    <p>{D.randomId()}</p>
    <p>{D.randomName()}</p>
    <p>{D.randomJobTitle()}</p>
    <p>{D.randomSentence()}</p>
    <img src={D.randomAvatar()} width={100} height={100} />
  </div>
));

const rootVirtualDOM = <div>{child}</div>;
const root = ReactDOM.createRoot(
  document.getElementById("root") as HTMLElement
);
root.render(rootVirtualDOM);

코드