관리 메뉴

거니의 velog

(5) JSX 2 본문

React_리액트 시작

(5) JSX 2

Unlimited00 2023. 11. 29. 08:46

4. JSX 문법

* JSX는 정말 편리한 문법이지만, 올바르게 사용하려면 몇 가지 규칙을 준수해야 한다.


(1) 감싸인 요소

* 컴포넌트에 여러 요소가 있다면 반드시 부모 요소 하나로 감싸야 한다. 한번 App.js 파일의 컴포넌트 함수 내부를 지우고 다음과 같이 작성해 보자. 상단에 있는 SVG와 CSS를 import하는 코드도 지워 보자.

import React from 'react';

function App() {
  return (
    <h1>리액트 안녕!</h1>
    <h2>잘 작동하니?</h2>
  );
}

export default App;

* 이런 형태의 코드는 제대로 작동하지 않는다. 코드를 저장한 후 웹 브라우저나 개발 서버를 실행했던 터미널을 열어 보자. 다음 오류가 나타날 것이다.

* 요소 여러 개가 부모 요소 하나에 의하여 감싸져 있지 않기 때문에 오류가 발생핬다. 이 오류를 다음과 같이 코드를 작성하여 해결할 수 있다.

function App() {
  return (
    <div>
      <h1>리액트 안녕!</h1>
      <h2>잘 작동하니?</h2>
    </div>
  );
}

export default App;

* 리액트 컴포넌트에서 요소 여러 개를 왜 하나의 요소로 꼭 감싸 주어야 할까? 그것은 Virtual DOM에서 컴포넌트 변화를 감지해 낼 때 효율적으로 비교할 수 있도록 컴포넌트 내부는 하나의 DOM 트리 구조로 이루어져야 한다는 규칙이 있기 때문이다.

* 그런데 여기서 꼭 div 요소를 사용하고 싶지 않을 수도 있다. 그런 경우에는 리액트 v16 이상부터 도입된 Fragment라는 기능을 사용하면 된다.

import { Fragment } from "react";

function App() {
  return (
    <Fragment>
      <h1>리액트 안녕!</h1>
      <h2>잘 작동하니?</h2>
    </Fragment>
  );
}

export default App;

* 코드 상단 import 구문에서 react 모듈에 들어 있는 Fragment라는 컴포넌트를 추가로 불러온다. Fragment는 다음과 같은 형태로도 표현할 수 있다.

import { Fragment } from "react";

function App() {
  return (
    <>
      <h1>리액트 안녕!</h1>
      <h2>잘 작동하니?</h2>
    </>
  );
}

export default App;

* 훨씬 간단하다. 브라우저에서도 결과물이 잘 나타나는지 확인해 보자.


(2) 자바스크립트 표현

* JSX가 단순히 DOM 요소를 렌더링하는 기능밖에 없었다면 뭔가 좀 아쉬웠을 것이다. JSX 안에서는 자바스크립트 표현식을 쓸 수 있다. 자바스크립트 표현식을 작성하려면 JSX 내부에서 코드를 {   } 로 감싸면 된다. 자바스크립트 값을 JSX에서 한번 렌더링해 보자.

import { Fragment } from "react";

function App() {
  const name = "리액트";
  return (
    <>
      <h1>{name} 안녕!</h1>
      <h2>잘 작동하니?</h2>
    </>
  );
}

export default App;

* 코드를 저장하고 브라우저로 확인해 보자. 오류 없이 조금 전과 같은 화면이 나타난다.

* ES6의 const와 let

(1) const는 ES6 문법에서 새로 도입되었으며, "한 번 지정하고 나면 변경이 불가능한 상수"를 선언할 때 사용하는
    키워드이다. 
    
(2) let은 동적인 값을 담을 수 있는 var 키워드를 사용했는데, var 키워드는 scope(해당 값을 사용할 수 있는 코드 영역)
    가 함수 단위이다.

function myFunction() {
	var a = "Hello";
    if(true) {
    	var a = "Bye";
        console.log(a); // bye
    }
    console.log(a); // bye
}
myFunction();

* if 문 바깥에서 var 값을 Hello로 선언하고, if 문 내부에서 bye로 설정했다. if 문 내부에서 새로 선언했음에도
  id 문 밖에서 a를 조회하면 변경된 값이 나타난다.
  
  이런 결점을 해결해 주는 것이 바로 let과 const이다.
  
function myFunction() {
	let a = 1;
    if(true) {
    	let a = 2;
        console.log(a); // 2
    }
    console.log(a); // 1
}
myFunction();

let과 const는 scope가 함수 단위가 아닌 블록 단위이므로, if 문 내부에서 선언한 a 값은 if문 밖의 a 값을 변경하지 않는다.

--------------------------------------------------------------------------------

let과 const를 사용할 때 같은 블록 내부에서 중복 선언이 불가능하다는 점에 주의하자.

let a = 1;
let a = 2; // 오류 : Uncaught SyntaxError: Identifier 'a' has already been declared

그리고 const는 한번 선언하면 재설정할 수 없다.

const b = 1;
b = 2; // VM74:2 Uncaught TypeError: Assignment to constant variable. at <anonymous>:2:3

그렇다면 어떤 상황에 각 키워드를 사용해야 할까?
일단 ES6 문법에서 var를 사용할 일은 없다. let은 한번 선언한 후 값이 유동적으로 변할 수 있을 때만
(예 : for문) 사용하고, const는 한번 설정한 후 변할 일이 없는 값에 사용한다.

편하게 생각하면 기본적으로 const를 사용하고, 해당 값을 바꾸어야 할 때는 let을 사용하면 된다.

(3) if 문 대신 조건부 연산자

* JSX 내부의 자바스크립트 표현식에서 if 문을 사용할 수는 없다. 하지만 조건에 따라 다른 내용을 렌더링해야 할 때는 JSX 밖에서 if 문을 사용하여 사전에 값을 설정하거나, {  } 안에 조건부 연산자를 사용하면 된다. 조건부 연산자의 또 다른 이름은 삼항 연산자이다. 이 연산자를 한번 사용해 보자.

import React from "react";

function App() {
  const name = "리액트";
  return (
    <div>
      {name === '리액트' ? (
        <h1>리액트입니다.</h1>
      ) : (
        <h2>리액트가 아닙니다.</h2>
      )}
    </div>
  );
}

export default App;

* 이렇게 코드를 작성한 후 저장하면 브라우저에서 '리액트입니다.' 라는 문구를 볼 수 있다. 하지만 name 값을 다음과 같이 다른 값으로 바꾸면?

const name = '뤼웩트';


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

* 개발하다 보면 특정 조건을 만족할 때 내용을 보여 주고, 만족하지 않을 때 아예 아무것도 렌더링하지 않아야 하는 상황이 올 수 있다. 이럴 때도 조건부 연산자를 통해 구현할 수는 있다.

import React from "react";

function App() {
  const name = "뤼웩트";
  return <div>{name === '리액트' ? <h1>리액트입니다.</h1> : null}</div>;
}

export default App;

* 위 코드와 같이 null을 렌더링하면 아무것도 보여주지 않는다.

* 하지만 이것보다 더 짧은 코드로 똑같은 작업을 할 수 있다. 다음과 같이 && 연산자를 사용해서 조건부 렌더링을 할 수 있다.

import React from "react";

function App() {
  const name = "뤼웩트";
  return <div>{name === '리액트' && <h1>리액트입니다.</h1>}</div>;
}

export default App;

* 이렇게 코드를 작성하고 나면 브라우저에 아무것도 나타나지 않을 것이다.

* 다시 name 값을 리액트로 설정하면 '리액트입니다.' 라는 문구가 나타날 것이다.

* && 연산자로 조건부 렌더링을 할 수 있는 이유는 리액트에서 false를 렌더링할 때는 null과 마찬가지로 아무것도 나타나지 않기 때문이다. 여기서 한 가지 주의해야 할 점이 있는데, falsy한 값인 0은 예외적으로 화면에 나타나게 된다.

const number = 0;
return number && <div>내용</div>

* 이런 코드는 화면에 숫자를 0으로 보여준다.

* JSX는 언제 괄호로 감싸야 하나요?

- JSX를 작성할 때 (<div>Hello World</div>)와 같이 괄호로 감쌀 때도 있고, 감싸지 않을 때도 있다.
  주로 JSX를 여러 줄로 작성할 때 괄호로 감싸고, 한 줄로 표현할 수 있는 JSX는 감싸지 않는다.
  JSX를 괄호로 감싸는 것은 필수 사항이 아니다. 감싸도 되고 감싸지 않아도 된다.

'React_리액트 시작' 카테고리의 다른 글

(7) JSX 4  (0) 2023.11.29
(6) JSX 3  (1) 2023.11.29
(4) JSX 1  (0) 2023.11.28
(3) 작업 환경 설정  (1) 2023.11.28
(2) 리액트의 특징  (0) 2023.11.28