JSX로 마크업 작성하기

soap·2025년 11월 4일

부족한 공부를 어떤 식으로 채워나가야 할 지를 고민하던 중, 나는 취준생이기에.. 이력서에 적은 프로젝트에 나올 수 있는 질문들을 추려서 하나씩 지워나가는 식으로 공부하기로 했다.

"Next.js의 SSR/CSR 중 어느 방식을 주로 채택했고, 선택 근거는 무엇이었나요?"

최근에 Next.js를 사용한 프로젝트에서 나올 법한 기본적인 질문이기에 먼저 시작했는데.. 난 기교만 부리는 개반인이였나보다..ㅋㅋㅋ

암튼.. JSX로 마크업 > React의 render와 commit > SSR,CSR순으로 정리를 시작하겠다.

JSX로 마크업 작성하기

HTML인척 하는 JSX는 확장된 문법이다. 이름에서부터 알 수 있는데 HTML이였다면 JSH였겠지만, JSX에서 X는 XML(eXtensible Markup Language)이다.
HTML 태그와 유사하지만 사용자가 자신의 태그를 정의할 수 있다는 점이 다르다.

내가 처음에 시작한 프로젝트는 거의 모든 입문자가 하는 바닐라JS 프로젝트였다.
HTML, CSS, JavaScript가 각각 분리된 파일로 있는 즉, 로직과 마크업을 분리한 형태인 파일 구조.
그 다음으로 이제 React를 사용하면서 JavaScript가 HTML을 담당하게 되는 프로젝트를 하게 되었다.

React에는 컴포넌트라는 개념이 있는데 그 개념을 구현하기 위해 JSX가 만들어진거라고 봐도.. 무방하다고 생각한다. React 컴포넌트는 React가 브라우저에서 마크업을 렌더링할 수 있는 JS함수 이기때문에 로직 + return을 통해 "값 하나"만 반환해야한다는 점이 기본 베이스다. 그렇기 때문에 HTML보다는 조금 엄격한(?) 규칙이 있다.

일단 HTML -> JSX로!

  • html
<h1>Hedy Lamarr's Todos</h1>
<img
  src="https://i.imgur.com/yXOvdOSs.jpg"
  alt="Hedy Lamarr"
  class="photo"
>
<ul>
    <li>Invent new traffic lights
    <li>Rehearse a movie scene
    <li>Improve the spectrum technology
</ul>
  • jsx
export default function TodoList(){
	return (
    	<h1>Hedy Lamarr's Todos</h1>
        <img
          src="https://i.imgur.com/yXOvdOSs.jpg"
          alt="Hedy Lamarr"
          class="photo"
        >
        <ul>
            <li>Invent new traffic lights
            <li>Rehearse a movie scene
            <li>Improve the spectrum technology
        </ul>
    );
}

당연히 오류가 난다.

앞서 말했듯이 엄격한(?) 규칙이 존재하기 때문이다.

JSX 규칙1: 하나의 루트엘리먼트로 반환하기

React에서 컴포넌트는 동적로직과 마크업을 JavaScript 객체로 반환하는 함수이기 때문에 값이 하나 여야 한다.

그렇기 때문에 한 컴포넌트 (한 함수)에서 여러개의 엘리먼트를 반환하려면 하나의 부모로 묶어줘야 한다.

보통 <div> 태그나 의미가 없는 <></>빈 태그로 묶어준다.
여기서 빈 태그를 Fragment라고 한다. 나도 주로 Fragments를 사용하여 브라우저상의 HTML 트리 구조에서 흔적을 남기지 않으려고 한다.


...

return(
  <>
    <h1>Hedy Lamarr's Todos</h1>
    <img
      src="https://i.imgur.com/yXOvdOSs.jpg"
      alt="Hedy Lamarr"
      class="photo"
    >
    <ul>
        <li>Invent new traffic lights
        <li>Rehearse a movie scene
        <li>Improve the spectrum technology
    </ul>
  </>
);

...

JSX 규칙2: 모든 태그는 닫아주기

JSX애서는 태그를 명시적으로 닫아줘야한다. <Img>처럼 자체적으로 닫아주는 태그도 반드시 <Img/><li> 같은 래핑 태그도 <li></li> 형태로 작성해서 닫아줘야 한다.

<>
  <img
    src="https://i.imgur.com/yXOvdOSs.jpg"
    alt="Hedy Lamarr"
    class="photo"
   />
  <ul>
    <li>Invent new traffic lights</li>
    <li>Rehearse a movie scene</li>
    <li>Improve the spectrum technology</li>
  </ul>
</>

JSX 규칙3: 속성은 거의~ 카멜케이스로

JSX는 브라우저가 직접 읽는 HTML이 아니라 Babel 같은 트랜스파일러에 의해 JavaScript 코드로 변환되기 때문에 속성 (attribute)들이 JavaScript 객체의 키(key)로 들어가는 구조이다.

const element = <div className="photo" strokeWidth="3"></div>;

//내부적으로 아래와 같이 바뀜
const element = React.createElement("div", {className : "photo", strokeWidth : "3"})

JS 변수명(객체 키)에는 제약이 있다는 것이다. JavaScript에서 객체를 아래와 같이 써보면

const obj = {
	stroke-width : 3,
    class: "photo"
}

문제가 생긴다.
1. - (대시)는 변수명에 쓸 수 없다. 빼기 연산으로 인식하기 때문이다
2. 예약어(class, for, default 등)는 변수명으로 쓸 수 없다.

따라서

const obj = {
	strokeWidth : 3,
    className: "photo"
}

그럼 이제 코드를 바꿔보면

export default function TodoList(){ //JS 함수
	return (
      <> //JSX 시작
    	<h1>Hedy Lamarr's Todos</h1>
        <img
          src="https://i.imgur.com/yXOvdOSs.jpg"
          alt="Hedy Lamarr"
          className="photo"
        />
        <ul>
            <li>Invent new traffic lights</li>
            <li>Rehearse a movie scene</li>
            <li>Improve the spectrum technology</li>
        </ul>
      </>
    );
}

이제..렌더링으로

profile
치열하게 살지는 않아도 후회되는 순간은 만들지 말자

0개의 댓글