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

devHagaa·2022년 6월 22일
post-thumbnail

이 포스팅은 김민준님의 '리액트를 다루는 기술'을 요약한 글입니다.

2.1 코드 이해하기

1장에서 만든 프로젝트를 VS Code에서 열고 파일 > 열기 메뉴를 선택하여 생성한 프로젝트의 디렉터리를 엽니다.

그리고 src/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;

이제부터 코드를 하나씩 이해해 봅시다.

import React from 'react';

이 코드는 리액트를 불러와서 사용할 수 있게 해 줍니다. 리액트 프로젝트를 만들 떄 node_modules라는 디렉터리도 함께 생성되는데 이 과정에서 node_modules 디렉터리에 react 모듈이 설치됩니다. 그리고 이렇게 import 구문을 통해 리액트를 불러와서 사용할 수 있습니다.


2.2 JSX란?

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

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

이렇게 작성된 코드는 다음과 같이 변환됩니다.

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

아래와 같이 매번 React.createElement 함수를 사용해야한 다면 매우 불편하기 때문에 JSX를 사용하여 매우 편하게 UI를 렌더링 할 수 있습니다.


2.3 JSX 장점

  • 보기 쉽고 익숙하다 = HTML코드를 작성하는 것과 비슷하다
  • 더욱 높은 활용도 = html 사용 가능, 컴포넌트도 jsx안에 작성 가능, 컴포넌트를 태그쓰듯이 작성
// index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

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

2.4 JSX 문법

2.4.1 감싸인 요소

반드시 1개의 부모 요소 안에 형제 노드가 들어갈 수 있습니다.

Virtural DOM에서 컴포넌드 변화 감지시 컴포넌트 내부는 하나의 DOM 트리 구조로 이루어져야 한다는 규칙이 있기 때문입니다.

// 오류 예시

import React from 'react';

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

이런 형태의 코드는 제대로 작동하지 않습니다.요소 여러 개가 부모 요소 하나에 의하여 감싸져 있지 않기 때문에 오류가 발생합니다.

// 정상 예시

import React from 'react';

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

이렇게 최상위에

와 같은 하나의 태그로 감싸주거나, 꼭 div 요소를 사용하고 싶지 않은 경우 리액트 v16 이상부터 도입된 Fragment라는 기능을 사용하면 됩니다.

// Fragment 예시

import React, { Fragment } from 'react';

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

Fragment는 다음과 같은 형태로도 표현할 수 있습니다.

// Fragment 예시

import React from 'react';

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

2.4.2 자바스크립트 표현

JSX 는 DOM 요소를 렌더링하는 기능과 더불어 JSX안에서 자바스크립트 표현식을 쓸 수 있습니다.

자바스크립트 표현식을 작성하려면 JSX 내부에서 코드를 { }로 감싸면 됩니다

import React from 'react';

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

2.4.3 if문 대신 조건부 연산자

JSX 내부의 자바스크립트 표현식에서 if 문을 사용할 수 없습니다.

조건에 따라 다른 부분 렌더링 해야 할 땐 JSX 밖에서 if문을 사용하거나 { } 안에 조건부연산자( 삼항연산자 )를 사용합니다.

import React from 'react';

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

결과
조건부 연산자 결과

const name = '뤼액트';

로 바꾼다면 결과는 아래와 같이 표시됩니다.
조건부 연산자 결과

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

리액트에서 false를 렌더링 할 때는 null과 마찬가지로 아무것도 나타나지 않기 때문에 아래와 같이 표시할 수 있습니다.

import React from "react";

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

export default App;

단, falsy한 값인 0은 예외적으로 화면에 나타납니다.

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

이런 코드는 화면에 숫자 0을 보여 줍니다.

2.4.5 undefined 렌더링하지 않기

리액트 컴포넌트에서는 undefined만 반환하여 렌더링하는 상황을 만들면 안 됩니다. OR(||) 연산자로 해당값이 undefined 일 때 사용할 값을 지정하면 오류를 방지할 수 있습니다.

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 <div>{name}</div>;
}

export default App;

name 값이 undefined일 때 보여 주고 싶은 문구가 있다면 다음과 같이 코드를 작성하면 됩니다.

import React from "react";

function App() {
  const name = undefined;
  return <div>{name || '리액트'}</div>;
}

export default App;

2.4.6 인라인 스타일링

직접 스타일 넣을 땐 카멜 표기법(camelCase)으로 작성해야 합니다. 단위 생략 시 px로 고정됩니다.

import React from "react";

function App() {
  const name = '리액트';
	const style = {
		backgroundColor: 'black',
		color: 'aqua',
		fontSize: '48px',
		fontWeight: 'bold',
		padding: 16 // 단위를 생략했으므로 16px로 고정
	};
  return <div style={style}>{name}</div>;
}

export default App;

또는 미리 선언하지 않고 바로 style 값을 지정할 땐

import React from "react";

function App() {
  const name = '리액트';
  return <div style={{
			backgroundColor: 'black',
			color: 'aqua',
			fontSize: '48px',
			fontWeight: 'bold',
			padding: 16 // 단위를 생략했으므로 16px로 고정
		}}
	>
		{name}
	</div>
};

export default App;

2.4.7 class 대신 className

JSX에서는 CSS 클래스를 사용할 때 class가 아닌 className으로 설정해야 합니다.

// App.css

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

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

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

class라고 적을 시 스타일이 적용되기는 하지만 console창에 아래와 같은 경고가 표시되니 주의하세요.
className console warning

2.4.8 꼭 닫아야 하는 태그

input HTML 요소는 <input></input>이라고 입력하지 않고 <input>이라고만 입력해도 작동하지만 JSX에서는 닫아줘야만 작동합니다.

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

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

또는 태그 사이에 별도의 내용이 들어가지 않는 경우에는 self-closing 태그를 이용하여 선언하면서 동시에 닫습니다.

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

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

2.4.9 주석

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

function App() {
	const name = '리액트';
	return (
		<>
		{/* 주석은 이렇게 작성합니다 */}
			<div 
				className="react" // 시작 태그를 여러 줄로 작성하게 된다면 여기에 주석을 작성할 수 있습니다.
			>
				{name}
			</div>
			// 하지만 이런 주석이나
			/* 이런 주석은 페이지에 그대로 나타나게 됩니다. */
			<input />
		</>
	);
}

주석 예시


2.5 ESLint와 Prettier 적용하기

ESLint는 문법 검사 도구이고, Prettier는 코드 스타일 자동 정리 도구입니다.

VS code 마켓플레이스에서 설치할 수 있습니다.
ESLint
ESLint는 코드를 작성할 때 실수를 하면 에러 혹은 경고 메시지를 VS code 에디터에서 바로 확인할 수 있게 해줍니다.

Prettier는 코드의 가독성을 위해 예쁘게 들여쓰기 및 정렬을 해줍니다.

‘F1’ 버튼을 누르고 format이라고 입력한 다음 ‘Enter’를 누르면 난잡한 코드를 정리해줍니다.

Prettier을 커스터마이징 하고 싶다면 현재 열려 있는 프로젝트의 루트 디렉터리에서 .prettierrc라는 파일을 생성한 후 다음의 내용을 입력합니다.

// .prettierrc

{
	"singleQuote": true,
	"semi": true,
	"useTabs": false,
	"tabWidth": 2
}

이 파일에서는 들여쓰기를 할 때 탭 대신 공백을 두 칸 사용하고 큰따옴표 대신 작은 따옴표를 쓰게 했고, 세미콜론은 언제나 붙이도록 설정했습니다. 자세한 내용은 Prettier Options 페이지를 참고하세요.

만약 저장할 때마다 자동으로 정리하게 하고 싶다면

  • Code (macOS) / 파일 (windows) > 기본 설정 > 설정 메뉴를 클릭
  • 상단 텍스트 박스에서 format on save를 검색하여 나타나는 체크 박스에 체크

만약 다른 포맷 도구를 설치했다면 충돌이 발생할 수 있으니 주의하세요.

profile
디자이너인가 퍼블리셔인가 프론트엔드개발자인가 정체성의 혼란을 겪는 개린이

0개의 댓글