본문 바로가기
리액트를 다루는 기술

[리액트를 다루는 기술] 2장 JSX

by 도리에몽 2022. 3. 7.
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>
);
}

function 키워드를 사용하여 만든 컴포넌트를 함수형 컴포넌트라고 부른다. 프로젝트에서 컴포넌트를 *렌더링하면 함수에서 반환하고 있는 내용을 나타낸다. 함수에서 반환하는 내용은 HTML으로 작성한 것처럼 보이지만 JSX로 이루어진 코드이다.

 

*렌더링: '보여 준다'는 것을 의미한다.

 

2.2 JSX란?

자바스크립트의 확장 문법으로 XML과 비슷하게 생겼다. JSX로 작성한 코드는 브라우저에서 실행되기 전, 코드가 번들링되는 과정에서 바벨을 사용하여 일반 자바스크립트 형태의 코드로 변환된다.

 

JSX 코드의 변환 

function App() {
  return (
    <div>
      Hello <b>react</b>
    </div>
  );
}

이렇게 작성된 코드가 아래와 같이 변환된다.

function App() {
return React.createElement(“div“, null, “Hello “, React.createElement(“b“, null, “react“));
}

 

2.3 JSX의 장점

1. 보기 쉽고 익숙하다.

2. 활용도가 높다.

 

2.4 JSX 문법

1. 감싸인 요소

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

 

- 오류가 나는 코드

import React from ‘react‘;
function App() {
  return (
    <h1>리액트 안녕!</h1>
    <h2>잘 작동하니?</h2>
  )
}
export default App;​

- 올바른 코드

import React from 'react';
function App() {
  return (
    <div>
      <h1>리액트 안녕!</h1>
      <h2>잘 작동하니?</h2>
    </div>
  );
}
export default App;

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

 

div 요소 대신  Fragment 기능을 사용해도 된다. import 구문에서 Fragment라는 컴포넌트를 추가로 불러온다.

import React, { Fragment } from 'react';
function App() {
  return (
    <Fragment>
      <h1>리액트 안녕!</h1>
      <h2>잘 작동하니?</h2>
    </Fragment>
  );
}
export default App;

Fragment는 다음과 같이 바꿔 쓸 수도 있다.

import React from 'react';
function App() {
  return (
    <>
      <h1>리액트 안녕!</h1>
      <h2>잘 작동하니?</h2>
    </>
  );
}
export default App;

 

2. 자바스크립트 표현

JSX 안에서는 자바스크립트 표현을 쓸 수 있다. 자바스크립트 표현식을 작성하려면 JSX 내부에서 코드를 { }로 감싸면 된다. 자바스크립트 값을 JSX에서 렌더링해 보자.

import React from 'react';
function App() {
  const name = '리액트';
  return (
    <>
      <h1>{name} 안녕!</h1>
      <h2>잘 작동하니?</h2>
    </>
  );
}
export default App;

- const와 let

const는 한번 지정하고 나면 변경이 불가능한 상수를 선언할 때 사용하는 키워드이다. 반면, let은 동적인 값을 담을 수 있는 변수를 선언할 때 사용하는 키워드이다. let과 const를 사용할 때 같은 블록 내부에서 중복 선언이 불가능하다. 또한, const는 한번 선언하면 재설정할 수 없다. let은 한번 선언 후 값이 유동적으로 변할 수 있을 때 사용하고, const는 한번 설정한 후 변할 일이 없는 값에 사용한다.

 

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;

 

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

특전 조건을 만족할 때 내용을 보여 주고, 만족하지 않을 때 아무것도 렌더링 하지 않는 상황을 조건부 렌더링을 통해 구현 가능하다.

import React from 'react';
function App() {
  const name = '뤼액트';
  return
    <div>
      {name === '리액트' ? <h1>리액트입니다.</h1> : null}
    </div>
}
export default App;

다음과 같이 null을 렌더링하면 아무것도 보여주지 않는다. JSX를 괄호로 감싸는 것은 필수 사항이 아니다. 지금은 한 줄로도 표현할 수 있기 때문에 괄호로 감싸지 않았다.

 

&& 연산자를 사용하면 더 짧은 코드로 똑같이 작업할 수 있다. && 연산자로 조건부 렌더링을 할 수 있는 이유는 리액트에서 false를 렌더링할 때는 null과 마찬가지로 아무것도 나타나지 않기 때문이다. 단, falsy한 값인 0은 예외적으로 화면에 나타난다.

import React from 'react';
function App() {
  const name = '뤼액트';
  return
    <div>
      {name === '리액트' && <h1>리액트입니다.</h1>}
    </div>
}
export default App;

 

5. undefined 를 렌더링하지 않기

리액트 컴포넌트에서는 함수에서 undefined만 반환하여 렌더링하는 상황을 만들면 안 된다.

//오류가 발생하는 코드
import React from 'react';
import './App.css';
function App() {
  const name = undefined;
  return name;
}
export default App;

어떤 값이 undefined일 수도 있다면, OR(||) 연산자를 사용하면 해당 값이 undefined일 때 사용할 값을 정할 수 있으므로 오류를 방지할 수 있다.

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

//JSX 내부에서 undefined를 렌더링하는 것은 됩니다.
function App() {
  const name = undefined;
  return <div>{name}</div>;
}

//name 값이 undefined일 때 보여 주고 싶은 문구가 있다면 다음과 같이 작성합니다.
function App() {
  const name = undefined;
  return <div>{name || '리액트'}</div>;
}

 

6. 인라인 스타일링

리액트에서 DOM 요소에 스타일을 적용할 때는 문자열 형태가 아닌 객체 형태로 넣어야 한다. 스타일 이름 중에 - 문자가 포함되는 이름은 카멜 표기법으로 작성한다. ex) background-color는 backgroundColor로 작성한다.

 

style 객체를 미리 선언하고 div의 style 값으로 지정할 수도 있고, 미리 선언하지 않고 바로 style 값을 지정할 수도 있다.

function App() {
  const name = ‘리액트‘;
  const style = {
    // 카멜 표기법 사용
    backgroundColor: ‘black‘,
    color: ‘aqua‘,
    fontSize: ‘48px‘, // font-size -> fontSize
    fontWeight: ‘bold‘, // font-weight -> fontWeight
    padding: 16 // 단위를 생략하면 px로 지정됩니다.
  };
  return <div style={style}>{name} </div>;
}

 

7. class 대신 className

JSX에서는 class가 아닌 className으로 설정해 준다.

- src/App.css

.react {
  background: aqua;
  color: black;
}

- src/App.js

import React from 'react';
import './App.css';
function App() {
  const name = '리액트';
  return <div className="react">{name}</div>;
}
export default App;

 

8. 꼭 닫아야 하는 태그

JSX에서는 태그를 닫지 않으면 오류가 발생한다.

//오류가 발생하는 코드
function App() {
  const name = ‘리액트‘;
  return (
    <>
      <div className=“react“>{name}</div>
      <input>
    </>
  );
}

//input 태그를 닫아 주어야 함
function App() {
  const name = ‘리액트‘;
  return (
    <>
      <div className=“react“>{name}</div>
      <input></input>
    </>
  );
}

태그 사이에 별도의 내용이 들어가지 않는 경우 태그를 선언하면서 동시에 닫을 수 있다. 

<input />

 

9. 주석

JSX 내부에서는 주석을 {/*  */} 형태로 작성한다. 시작 태그를 여러 줄로 작성할 때는 그 내부에서 //를 사용하여 주석을 작성할 수 있다.

 

2.5 Prettier

프로젝트의 루트 디렉터리에서 .prettierrc 파일을 생성하여 코드 스타일을 사전 설정할 수 있다. 자바스크립트에서 문자열을 표현할 때 작은따옴표와 큰따옴표는 상관없다. 세미콜론은 코드 뒷부분에 무조건 있어야 하는 것은 아니다.