2.4장. JSX문법

2.4.1 감싸인 요소

컴포넌트에 여러 요소가 있다면 부모 요소로 하나로 감싸줘야한다. 아래의 코드와 같이 작성해보자(상단의 SVG, CSS를 import하는 코드도 지우자)

💡 react 환경을 시작하고 싶다면 vscode 맨 끄트머리를 당겨보면 터미널이 나오는데 경로를 react 폴더로 넣고 npm start를 하면 된다. 환경을 종료하고 싶다면 컨트롤+C를 두~세번 눌러주면 된다.

//src/App.js
import React from 'react';

function App() {
  return (
    <h1>Hello React!</h1>
    <h2>동작해 ?</h2>
  );
}

export default App;
//요소 여러 개가 부모 요소에 감싸져있지않아 오류를 출력한다.

이러한 코드는 다음과 같이 코드를 수정해 주어야 한다.

import React from 'react';

function App() {
  return (
    <div>
      <h1>Hello React!</h1>
      <h2>동작해 ?</h2>
    </div>
  );
}

export default App;
//만약 글씨가 빨간색으로 도배됐을땐 강제 새로고침을 활용하자

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

<div></div> 대신 <></>나 <Fragmenet></Fragmenet>를 활용해도 된다.(v16부터 도입된 기능)
import React, { Fragment } from 'react';

function App() {
  return (
    <Fragment>
      <h1>Hello React!</h1>
      <h2>동작해 ?</h2>
    </Fragment>
  );
}

export default App;
//import 구문에 Fragment도 넣어주자!

2.4.2 자바스크립트 표현

JSX안에서는 자바스크립트 표현식을 쓸 수 있는데, 작성하려면 JSX 내부에서 코드를 {}로 감싸면 된다. 아래의 코드를 살펴보자

import React from 'react'; //Fragment를 쓰지 않으니 삭제했다.

function App() {
  const name = 'react';
  return (
   <>
      <h1>{name} 안녕!</h1>
      <h2>동작중이니?</h2>
   </>
  );
}

export default App;

2.4.3 if 문 대신 조건부 연산자

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

import React from 'react';

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

export default App;

'react'와 '리액트'는 다르기 때문에 '리액트가 아닙니다'라는 문자를 볼 수 있다.

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

특정 조건을 만족할 때 내용을 보여주거나, 만족하지 않을 때 아예 아무것도 렌더링하지 않아야 하는 상황일 때 조건부 연산자를 통해 구현할 수 있다.

import React from 'react';

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

export default App;
//리액트가 아니기 때문에 빈 화면을 출력한다.

위의 코드보다 더 짧게도 표현이 가능하다.

import React from 'react';

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

export default App;
//위의 코드와 같이 빈 화면을 출력한다.

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

💡 JSX는 언제 괄호로 감싸야 하나요?
JSX를 여러 줄로 작성할 때는 감싸지만 한 줄로 표현할 수 있을 때는 감싸지 않는다. JSX를 괄호로 감싸는 것은 필수 사항이 아니다.

2.4.5 undefined를 렌더링하지 않기

리액트 컴포넌트에서는 undefined만 반환하여 렌러딩하는 상황을 만들면 안 된다. 아래와 같은 코드는 오류를 발생시킨다.

import React from 'react';

function App() {
  const name = undefined;
  return name;
}

export default App;
//error 발생코드

따라서 undefined일 수도 있다면 OR(||) 연산자를 사용해 오류를 방지한다.

import React from 'react';

function App() {
  const name = undefined;
  return name || '값이 undefined입니다.';
}

export default App;

반면 JSX 내부에서 undefined를 렌더링하는 것은 괜찮다.

import React from 'react';

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

export default App;
//빈화면 출력

2.4.6 인라인 스타일링

리액트에서 DOM 요소에 스타일을 적용할 때는 문자열이 아닌 객체 형태로 넣어주여야한다. background-color같은 경우는 카멜 표기법(camelCase)으로 작성해야한다.(backgroundColor로 작성하라는 소리)

import React from 'react';

function App() {
  const name = '리액트';
  const style = {
    backgroundColor: 'black',
    color: 'aqua',
    fontSize: '48px',
    fontWeight: 'bold',
    padding: 16 //단위가 없는 경우는 px이다.
  }
  return <div style={style}>{name}</div>
}

export default App;
//객체를 선언하고 만드는 방법
import React from 'react';

function App() {
  const name = '리액트';
  return <div style={{
      backgroundColor: 'black',
      color: 'aqua',
      fontSize: '48px',
      fontWeight: 'bold',
      padding: 16 
    }}>{name}</div>
}

export default App;
//바로 style을 지정하는 방법 {}를 하나 더 감싸준다

2.4.7 class 대신 className

HTML에서 css 클래스를 사용할 때는 class라는 속성을 설정하지만 JSX에서는 className으로 설정해 주어야 한다.

src 디렉터리 안에 App.css를 열어 새 style을 작성하자

.react{
  background-color: aqua;
  color: black;
  font-size: 48px;
  font-weight: bold;
  padding: 16px; 
}

이제 App.js 파일에서 상단에 App.css를 불러온 뒤 div에 className 값을 지정해 준다.

import React from 'react';
import './App.css';

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

export default App;
//바로 style을 지정하는 방법 {}를 하나 더 감싸준다

class 값을 설정해도 스타일이 적용되지만 v16 이상부터는 class를 className으로 변환시켜 주고 경고를 띄운다.

2.4.8 꼭 닫아야하는 태그

HTML 코드를 작성할 때 가끔 태그를 닫지 않는 상태로 코드를 작성한다.

<form>
  성: <br>
  <input><br>
  이름: <br>
  <input>
</form>

<!-- br과 input 태그는 열기만 하고 닫지 않은 상태 -->

JSX에서 html처럼 코드를 사용한다면 오류가 발생한다.

import React from 'react';
import './App.css';

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

export default App;

그래서 다음과 같이 self-closing을 이용해 닫아주어야한다.

import React from 'react';
import './App.css';

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

export default App;
//<input></input>도 가능하다

2.4.9 주석

JSX 안에서 주석을 작성하는 방법은 일반 자바스크립트에서 주석을 작성할 때와 다르다. 다음 코드를 살펴보자

import React from 'react';
import './App.css';

function App() {
  const name = '리액트';
  return (
    <>
      {/* 괴랄한 주석.. */}
       <div 
         className="react" //여러 줄로 작서하면 이런 주석은 가능하다.
        >
         {name}
       </div>
       // 이런 주석
      /* 이런 주석은 잘보인다. */
      <input/>
   </>
  );
}

export default App;


2.4장에서 배울게 조금 많아서 일부러 나눠서 올렸다.. 머리가 터질것 같은 느낌이다..🤯

좋은 웹페이지 즐겨찾기