본문 바로가기
개발공부일지/React

React - JSX 문법 기초 이해하기

by Hynn1429 2023. 2. 23.
반응형

안녕하세요.

Hynn 입니다.

 

이번 포스팅에서는 React 를 사용하기 위해 기본적으로 이해해야하는 JSX 문법의 대한 기초적 사항을 학습하려고 합니다.

시작해보도록 하겠습니다.

 

==============

==============

 

JSX 는, JavaScript XML의 약자로, JavaScript 의 기존 문법에서, 확장된 문법입니다.

React 에서의 JSX 는 본질적으로 Component 를 이용해서 UI(User Interface) 를 rendering 하는 로직과 연결된다는 사실을 이해하고, 받아들여야 합니다. 

이 로직에는 Event 가 처리되는 방식, 시간이나 이벤트 발동에 따라 State 가 바뀌는 방식, 이를 이용한 화면에 표시하는 데이터가 준비되는 과정들을 이해해야 합니다. 

 

이 JSX 를 이용하기 위해서는, 문법의 이해 뿐 아니라, JavaScript Code 내에서 UI 작업을 할때, 보다 시각적으로 도움이 된다고 생각하는 사용자들이 많습니다.

가령 예를 들면 아래의 코드를 비교해보도록 하겠습니다. 

 

JavaScript

Hello = (props) => {
    return React.createElement(
      "div",
      null,
      React.createElement("h1", null, "Hello, ", props.name, "!"),
      React.createElement("p", null, "Welcome to my React app.")
    )
  }

JSX 

Hello = (props) => {
  return (
    <div>
      <h1>Hello, {props.name}!</h1>
      <p>Welcome to my React app.</p>
    </div>
  );
}

시각적으로 위의 JavaScript 문법만으로 작성한 것 보다, 시각적으로 더 쉽게 눈에 이해될 뿐 아니라, 직관적이고, 작성자가 코드를 작성할 때 어떠한 결과물일지를 보다 직관적으로 볼 수 있도록 해주십니다. 

여기서 React 는 JSX 문법을 사용함으로서, 더욱 도움이되는 에러 및 경고를 표시할 수 있도록 지원하기 때문에, 당연하게도 이해를 해야, 실제 사용에서 더욱 효과적으로 사용을 할 수 있습니다.

 

 

 

JSX 표현식에서 가장 중요한 것은 바로 "{ }" 입니다. 바로 JSX 에서는 중괄호를 사용해서 표현식을 삽입할 수 있기 때문입니다.

이를 이용햇서 HTML에 동적인 값을 제 이전 프로젝트에서 Nunjucks 처럼 동적인 값이나 로직을 삽입할 수 있습니다.

이를 몇가지 예제 코드를 이용해서 살펴보면 아래와 같습니다. 

 

const name = "Hynn"
const element = <h1>Hello, {name}</h1>

const root = ReactDOM.createRoot(document.getElementById("root"))
root.render(element)

위의 코드의 구현방식을 살펴보도록 하겠습니다.

먼저 각각의 const 를 통해, name, element 를 선언합니다.

name 이라는 변수에는 "Hynn" 을, element 라는 변수에는 JSX 문법을 이용해서 <h1> Hello, {name}</h1> 을 담았습니다.

 

이를 이제 React 의 기초구조인 <div id="root"></div> 를 생성하고, 그를 ReactDOM.createRoot 를 사용해서 지정을 한뒤, "root.render" 를 이용해 element 를 표현하면, name 이라는 변수는 Hello, {name} 이라고 표기한 위치에 표현식으로서 값이 표시가 되게 됩니다.

 

이를 JSX 표현식의 가장 기초적인 방법입니다. 또한, JSX 역시 표현식이기도 하다는 의미입니다.

이를 다양한 방법으로도 표현할 수 있습니다.

 

가령 예를 들면 아래와 같이 표현식도 설정할 수 있습니다.

 

const element = <h1>Hello, {'w'+'o'+'r'+'l'+'d'}</h1>
const root = ReactDOM.createRoot(document.getElementById("root"))
root.render(element)

위의 예제에서는 " { } " 내에 JavaScript 형식의 표현식을 삽입한 예제입니다.

즉 중괄호 내에 각각의 문자열을 하나씩 두고, 그를 조합하는 표현식을 삽입했습니다.

 

그리고 난 뒤에, ReactDOM.createRoot() 라는 React 기본 method 를 이용해

"root" 라는 div 내에 render() method 를 이용해 표현합니다.

 

혹은, 우리가 기존에 잘 알고있는, If 구문이나 for, for loop 안에 JSX 를 사용하여, 변수에 할당, 인자값으로 받아 함수에서 반환을 받을 수도 있습니다. 

이에 대한 예시를 한번 사용해보면 아래와 같습니다. 또한 여기서 삼항연산자와 같은 가독성을 효과적으로 활용할 수도 있습니다.

 

예제 역시 같이 살펴보도록 하겠습니다.

 

If & 삼항연산자를 사용한 예

const Hello = (props) => {
        return (<h1>Hello, {props.name ? props.name : 'Hynn'}</h1>)
    }
    const root = ReactDOM.createRoot(document.getElementById("root"));
    root.render(<Hello name="world" />)

위 코드를 살펴보면, Hello 라는 변수에 화면에 Rendering 할 요소를 담습니다. 

return 내에 JSX 표현식을 사용하여 <h1> HTML Element 안에 Hello, 이후에 props.name 이 정의되어 있다면, 그 값을, 그렇지 않다면 Hynn 을 표현하도록 If 문을 삼항연산자를 이용해서 조건부를 설정합니다. 

 

그리고 ReactDOM.createRoot() method 를 사용해서 ID가 root 인 div를 요소에 연결한 뒤, root.render method 에 Hello Component 을 render 하도록 하되, props 의 "name" 속성을 "world" 로 표현하므로, 결과물은 Hello, World 가 표시됩니다. 만약 name 속성을 부여하지 않는다면 Hello, Hynn 이 표현되도록 작성된 표현식입니다.

 

For 문을 사용한 예제

const NumberList = (props) => {
        const numbers = props.numbers
        const listItems = []
        for (let i = 0; i < numbers.length; i++) {
            listItems.push(<li key={i}>{numbers[i]}</li>)
        }
        return <ul>{listItems}</ul>
        }
    const numbers = [1, 2, 3, 4, 5]
    const root = ReactDOM.createRoot(document.getElementById("root"));
    root.render(<NumberList numbers={numbers} />)

위 예제 역시 동일한 원리로 작성했습니다.

NumberList 라는 변수에 "Props" 라는 인자값을 받도록 하고, 지역변수로 각각 numbers 에는 props.numbers 를, listItems 에는 빈 배열을 담습니다.

그리고 난뒤 for 문을 사용해서 "listItems" 에 push 하는 형태로 <li>에 key={i}, {numbers[i]}</li> 를 표현하도록 반복문을 작성합니다.

그리고 난 뒤 numbers 에는 1,2,3,4,5 라는 배열로 값을 담습니다.

그리고 마찬가지로 root.render 를 이용해 화면을 그릴 때, Component 인 NumberList 를 표현하고 Props.numbers 에는 numbers 라는 배열을 담게되면, 자동으로 for 문이 반복하여, 1,2,3,4,5 를 구현하도록 작성되어 있습니다. 

 

 

 

먼저 이를 이해하기 위해 문법을 작성할 때 중요한 요소가 있습니다.

바로 HTML Element 를 작성하는 Tag 가 비어있거나, 끝날 때 반드시 " />" 을 이용해 닫아야 합니다.

일반적으로 HTML Element 를 사용할때는, "<h1> </h1>" 과 같은 형태에서는 관계가 없지만, Input 과 같은 Tag 나, Component 를 호출할때는 반드시 이 태그를 " /> " 으로 표현하여 닫아야 합니다.

 

즉 아래와 같이 닫아야 합니다.

root.render(<NumberList number={number} />)

root.render(<h1> Hello </h1>

root.render(<input />

 

또한 React 에서의 Parents & Children Element 정의는 다음 포스팅에서 살펴보게 될 Component 요소에서는 반드시 이해가 필요합니다.

 가장 쉽게 이해하는 Parents & Children Element 정의는 아래와 같은 예제를 볼 수 있겠습니다.

const element = (
        <div>
            <h1>Hello</h1>
            <h2>Hynn Tistory</h2>
        </div>
    )

즉 위 예제에서는 Parents 가 <div> 가 되고, 그 안의 요소로 H1,H2 가 각각 존재하는 것을 알 수 있습니다.

이를 Tree 형태로도 이해할 수 있어야 합니다. 이는 이후에 Component 에서 조금 더 자세하게 살펴보도록 하겠습니다. 

 

 

 

JSX 는 위에서 설명했듯이, JavaScript 가 확장된 문법입니다.

하지만 Browser 입장에서는 JSX 는 올바른 JavaScript 문법이라고 이해하지 못합니다. 즉, HTML은 HTML 이고, JavaScript 는 JavaScript 라는 별개의 언어로 인지하고 있지만, JSX작성은 JavaScript + HTML 하나의 파일에서 작성이 되었다 보니, 브라우저 입장에서는 이를 각각 개별적으로 읽어올 수 없고, 오류를 발생시키게 됩니다.

 

예를 들어 위의 코드가 포함된 전체 형식을 아래와 같이 작성하면 오류가 발생합니다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
</head>
<body>
    <div id="root"></div>
    <script type="text/javascript">
    const element = (
        <div>
            <h1>Hello</h1>
            <h2>Hynn Tistory</h2>
        </div>
    )
    const NumberList = (props) => {
        const number = props.number
        const listItems = []
        for (let i = 0; i < number.length; i++) {
            listItems.push(<li key={i}>{number[i]}</li>)
        }
        return <ul>{listItems}</ul>
        }
    const number = [1,2,3,4,5,6,7,8,9,10]
    const root = ReactDOM.createRoot(document.getElementById("root"));
    root.render(<NumberList number={number} />)    
    </script>
</body>
</html>
Uncaught SyntaxError: Unexpected token '<'

 

하지만 이를 Babel 을 사용함으로써, 개발자는 별도의 과정을 거치지 않고도, JSX 문법을 JavaScript 로 변환하는 기능을 가지고 있습니다.

이를 통해 다양한 브라우저 환경이나, NodeJS 와 같은 다양한 환경에 별도의 설정 없이도 대응이 가능합니다.

 

Babel 을 사용하기 위해서는 아래의 두개의 작업만 해주시면 손쉽게 사용이 가능합니다.

 

1) CDN 추가하기

<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

2) Script type 설정하기

<script type="text/babel"></script>

 

위 작업을 모두 거쳤다면, 아래와 같이 코드를 작성하면, 올바르게 화면이 랜더링 되는 것을 볼 수 있습니다.

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@18/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 element = (
        <div>
            <h1>Hello</h1>
            <h2>Hynn Tistory</h2>
        </div>
    )
    const NumberList = (props) => {
        const number = props.number
        const listItems = []
        for (let i = 0; i < number.length; i++) {
            listItems.push(<li key={i}>{number[i]}</li>)
        }
        return <ul>{listItems}</ul>
        }
    const number = [1,2,3,4,5,6,7,8,9,10]
    const root = ReactDOM.createRoot(document.getElementById("root"));
    root.render(<NumberList number={number} />)    
    </script>
</body>
</html>

 

다음 포스팅에서는 Element 을 React 에서 어떻게 이해하는지에 대한 간략한 내용을 가지고 뵙도록 하겠습니다.

감사합니다.

반응형

댓글