본문 바로가기
프론트엔드/리액트를 다루는 기술

리액트를 다루는 기술, JSX

by Hyeon_E 2023. 6. 11.

[ 2.1 코드 이해하기 ]

//App.js
import React from "react";
import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

 

리액트 프로젝트를 만들때 node_modules라는 디렉터리도 함께 생성됨

프로젝트 생성과정에서 node_modules 디렉터리에 react 모듈이 설치됨 

그것을 import 구문을 통해 리액트를 불러와서 사용할 수 있음

 

import React from "react";

 

모듈을 불러와서 사용하는 것은 원래 브러우저에서는 없는 기능

브러우저가 아닌 환경에서 JS를 실행할 수 있게 해 주는 환경인 Node.js에서 지원하는 기능

Node.js에서는 import가 아닌 require 구문으로 패키지를 불러올수 있음

 

이러한 기능을 브라우저에서도 사용하기 위해 번들러(bundler)를 사용함

번들은 묶는다는 뜻으로 즉 번들러는 파일을 묶듯이 연결하는 것

 

대표적인 번들러로 웹팩을 사용하는 추세임. 이유는 편의성과 확장성이 다른 도구보다 뛰어나기 때문

번들러 도구를 사용하면 import로 모듈을 불러왔을 때 불러온 모듈을 모두 합쳐서 하나의 파일로 생성해주며

최적화 과정에서 여러개의 파일로 분리 될 수도  있음

 

이책에서는 src/index.js를 시작으로 필요한 파일을 불러와 번들링함

 

웹팩을 사용하면 SVG파일(이미지 데이터를 저장하고 표현하기 위한 파일 형식)과 CSS 파일도 불러와서 사용할 수 있음

파일들을 불러오는 것은 웹팩의 로더(loader)라는 기능이 담당

  • css-loader: CSS파일을 불러오게 해줌
  • file-loader: 웹 폰트나 미디어파일 등을 불러올 수 있게 함
  • babel-loader: 최신 JS 문법으로 작성된 코드를 바벨을 사용해 ES5 문법으로 변환해줌
더보기

최신 JS로 작성된 코드를 변환하는 이유

ES5 형태로 변환하는 것은 구버전 웹 브라우저와 호환하기 위해서

리액트 컴포넌트에서 사용하는 JSX라는 문법도 정식 JS문법이 아니므로 ES5 형태의 코드로 변환해야함

 

웹팩의 로더는 create-react-app이 모두 대신해 주기 때문에 별도의 설정을 할 필요가 없음(커스터마이징 가능)

 

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

 

위 코드는 App이라는 컴포넌트(사용자 인터페이스를 구성하는 독립적인 재사용 가능한 부분)를 만들어 줌

function 키워드를 사용해 만든 컴포넌트함수형 컴포넌트라고 부름

프로젝트에서 컴포넌트를 렌더링(보여줌)하면 함수에서 반환하고 있는 내용을 나타냄

함수에서 반환하는 내용이 마치 HTML처럼 보이지만 이것은 JSX

 

[ 2.2 JSX란? ]

JSX는 JS이 확장 문법

JSX로 작성한 코드는 브라우저에서 실행되기 전에 코드가 번들링되는 과정에서

바벨을 사용하여 일반 JS 형태의 코드로 변환됨. JSX를 사용하면 편하게 UI를 렌더링 할 수 있음

 

더보기

JSX도 JS문법인가?

공식적인 JS 문법이 아님

바벨에서는 여러 문법을 지원할 수 있도록 preset 및 plugin을 설정함

바벨을 통해 개발자들의 임의로 만든 문법, 혹은 차기 JS 문법들을 사용할 수 있음

 

[ 2.3 JSX의 장점 ]

// src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

JS로 작성하면 일반 JS로만 사용한 코드보다 가독성이 높고 작성하기도 쉬움

또한 컴포넌트도 JSX 안에서 작성이 가능함(컴포넌트를 마치 HTML 태그 쓰듯이 작성)

 

더보기

ReactDOM.render란?

컴포넌트를 페이지에 렌더링하는 역할을 하며 react-dom 모듈을 불러와 사용할 수 있음

함수의 첫번째 파라미터에는 페이지에 렌더링할 내용을 JSX형태로 작성하고

두번째 파라미터에는 해당 JSX를 렌더링 할 document 내부 요소를 설정함

위 코드에는 id가 root인 요소 안에 렌더링을 하도록 설정되어 있음

public/index.html 파일에서 확인 가능함

 

React.StricMode란?

React.StricMode는 리액트 프로젝트에서 리액트의 레거시 기능들을 사용하지 못하게 하는 기능

나중에는 완전히 사랒지게 될 옛날 기능을 사용했을 때 경고를 출력함

 

[ 2.4 JSX 문법 ]

▶ 2.4.1 감싸인 요소

import React from "react";

function App() {
  return (
    <div>
      <h1>React Hi!</h1>
    </div>
  );
}

export default App;

 

컴포넌트에 여러 요소가 있다면 반드시 부모 요소 하나로 감싸야 함

VirtualDOM에서 컴포넌트 변화를 감지해 낼때 효율적으로 비교할 수 있도록

컴포넌트 내부는 하나의 DOM 트리 구조로 이루어져야 한다는 규칙이 있기 때문

 

div 요소로 꼭 감싸줄 필요는 없음. 이럴 경우에는 v16이상부터 도입된 Fragment라는 기능을 사용하면 됨

 

import React from "react";

function App() {
  return (
    <>
      <h1>React Hi!</h1>
    </>
  );
}

export default App;

 

▶ 2.4.2 JS 표현

JSX 안에서는 JS 표현식을 쓸 수 있음

JS 표현식을 작성하려면 JSX 내부에서 코드를 { }로 감싸면 됨

 

import React from "react";

function App() {
  const name = "React";
  return (
    <>
      <h1>{name} Hi!</h1>
    </>
  );
}

export default App;

 

▶ 2.4.3 if문 대신 조건부 연산자(삼항 연산자)

JSX 내부의 JS 표현식에서 if문을 사용할 수 없음

하지만 조건에 따라 다른 내용을 렌더링 할때는 JSX 밖에서 if문을 사용하거나, { } 조건부 연산자를 사용하면 됨

 

import React from "react";

function App() {
  const name = "React";
  return (
    <>
      {name === "React" ? <h1>{name} 입니다</h1> : <h1>{name}가 아닙니다</h1>}
    </>
  );
}
export default App;

 

▶ 2.4.4 AND 연산자(&&)를 사용한 조건부 렌더링

특정조건을 만족할때만 렌더링을 하고 만족하지 않을때는 렌더링을 하지 않는 상황에는

조건부 연산자를 통해 구현할 수 있음

 

import React from "react";

function App() {
  const name = "React";
  return <>{name === "React" ? <h1>{name} 입니다</h1> : null}</>;
}
export default App;

 

null을 렌더링하면 아무것도 보여주지 않음

위의 코드를 && 연산자를 사용해서 조건부 렌더링을 하면 더 짧은 코드로 똑같이 작업할 수 있음

 

import React from "react";

function App() {
  const name = "React";
  return <>{name === "React" && <h1>{name} 입니다</h1>}</>;
}
export default App;

 

&&연산자로 조건부 렌더링 할 수 있는 이유는

리액트에서 false를 렌더링할 때는 null과 마찬가지로 아무것도 나타나지 않기 때문

한가지 주의해야 할 점은 falsy한 값인 0은 예외적으로 화면에 나타남

 

▶ 2.4.5 undefined를 렌더링하지 않기

리액트 컴포넌트에서는 함수에서 undefined만 반환하여 렌더링 하는 상황에는 오류를 발생시킴

그래서 어떤 값이 undefined일 수도 있다면 OR(||) 연산자를 사용해

해당 값이 undefined일 때 사용할 값을 지정할 수 있어 간단하게 오류를 방지할 수 있음

function App() {
  const name = undefined;
  return name || "값이 undefined입니다";
}
export default App;

 

JSX 내부에서 undefined를 렌더링하는 것은 괜찮음

 

function App() {
  const name = undefined;
  return <div>{name}</div>;
}
export default App;

 

▶ 2.4.6 인라인 스타일링

DOM 요소에 스타일을 적용할 때는 문자열 형태로 넣는 것이 아니라 객체 형태로 넣어주어야 함

스타일 이름에 - 문자를 없애고 카멜스(camelCase)로 작성해야함

 

function App() {
  const name = "리액트";
  const style = {
    backgroundColor: "red",
    fontSize: "48", //단위를 생략하면 px로 지정됨
  };
  return <div style={style}>{name}</div>;
}
export default App;

 

미리 선언하지 않고 바로 style 값을 지정할 수 있음

 

function App() {
  const name = "리액트";
  return (
    <div
      style={{
        backgroundColor: "red",
        fontSize: "48", //단위를 생략하면 px로 지정됨
      }}
    >
      {name}
    </div>
  );
}
export default App;

 

▶ 2.4.7 class 대신 className

JSX에서는 class가 아닌 className으로 설정해주어야 함

import "./App.css";

function App() {
  const name = "리액트";
  return <div className="react">{name}</div>;
}
export default App;

댓글