2장. JSX
2.1 코드이해하기
import React from 'react';
→ react 모듈을 통해 리액트를 불러와서 사용할 수 있게 해준다.
- 프로젝트 생성 과정에서 node_modules 디렉터리에 react 모듈이 설치되어 리액트를 불러와서 사용할 수 있게 해 준다.
- 번들러(bundler)를 사용하여 import(또는 require)로 모듈을 불러올 때 불러온 모듈을 모두 합쳐서 하나의 파일을 생성함
→ 대표적인 번들러: 웹팩, Parcel, browserify
import logo from './logo.svg';
import './App.css';
- 웹팩의 로더(loader)가 SVG, CSS 파일을 불러옴
function App() {
return(
<div className="App">
...생략...
</div>
);
}
- function 키워드를 통해 App이라는 컴포넌트를 생성 → 함수형 컴포넌트라고 부름
- 프로젝트에서 컴포넌트를 렌더링하면 함수에서 반환하고 있는 내용을 나타냄
- 함수에서 반환하는 코드는 JSX라고 부름
2.2 JSX란?
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"));
}
→ 위 코드처럼 매번 작성해야 한다면 불편할 것이므로 JSX를 사용하여 매우 편하게 UI를 렌더링할 수 있다.
2.3. JSX의 장점
- 보기 쉽고 익숙하다 : 일반 자바스크립트보다 JSX로 작성하는 코드가 더 가독성이 높고 작성하기 쉽다. (HTML 코드와 유사)
- 더욱 높은 활용도 : div와 span과 같은 HTML 태그를 사용할 수 있을 뿐 아니라, 앞으로 만들 컴포넌트도 작성할 수 있다.
src/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')
);
→ App 컴포넌트를 마치 HTML 태그 쓰듯이 그냥 작성한다.
▶ ReactDOM.render 이란?
이 코드는 컴포넌트를 페이지에 렌더링하는 역할을 하고, react-dom 모듈을 불러와 사용할 수 있다.
이 함수의 첫 번째 파라미터에는 페이지에 렌더링할 내용을 JSX 형태로 작성하고, 두 번째 파라미터에는 해당 JSX를 렌더링할 document 내부 요소를 설정한다.
▶ React.StrictMode는 무엇인가?
이 코드는 리액트 프로젝트에서 리액트의 레거시 기능들을 사용하지 못하게 하는 기능이다. 이를 사용하여 나중에 완전히 사라지게 될 옛날 기능을 사용했을 때 경고를 출력한다.
2.4 JSX 문법
1) 감싸인 요소
컴포넌트에 여러 요소가 있다면 반드시 부모 요소 하나로 감싸야 한다.
※ Virtual DOM에서 컴포넌트 변화를 감지해낼 때 효율적으로 비교할 수 있도록 컴포넌트 내부는 하나의 DOM 트리 구조로 이루어져야 한다는 규칙 때문이다.
------작동하지 않는 코드-------
import React from 'react';
function App(){
return (
<h1>리액트 안녕!</h1>
<h2>잘 작동하니??</h2>
)
}
export dafault App;
↓
-------오류 해결-------
import React from 'react';
function App(){
return (
<div>
<h1>리액트 안녕!</h1>
<h2>잘 작동하니??</h2>
</div>
);
}
export dafault App;
※ 리액트 v16 이상부터는 div요소 대신에 Fragment라는 기능을 사용할 수 있다
------Fragment 사용 ver.1------
import React, {fragment} from 'react';
function App(){
return (
<Fragment>
<h1>리액트 안녕!</h1>
<h2>잘 작동하니??</h2>
</Fragment>
);
}
export dafault App;
------Fragment 사용 ver.2------
import React from 'react';
function App(){
return (
<>
<h1>리액트 안녕!</h1>
<h2>잘 작동하니??</h2>
</>
);
}
export dafault App;
2) 자바스크립트 표현
자바스크립트 표현식을 작성하려면 JSX 내부에서 코드를 { }로 감싸면 된다.
import React from 'react';
function App() {
const name = '리액트';
return (
<>
<h1>{name} 안녕!</h1>
<h2>잘 작동하니??</h2>
</>
);
}
export dafault App;
▶ const는 ES6 문법에서 새로 도입된 것으로 한번 지정하고 나면 변경이 불가능한 상수를 선언할 때 사용하는 키워드이고, let은 동적인 값을 담을 수 있는 변수를 선언할 때 사용하는 키워드이다.
- let과 const의 영역은 함수 단위가 아닌 블록 단위 (scope가 함수 단위인 var의 결점을 해결)
- let과 const를 사용할 때는 같은 블록 내부에서 중복 선언 불가능
-----var 사용-----
function myFunction() {
var a=1;
if(true) {
var a=2;
console.log(a); //2
}
console.log(a); //2
}
myFunction();
-----let 사용-----
function myFunction() {
let a = 1;
if(true) {
let a = 2;
console.log(a); //2
}
console.log(a); //1
}
myFunction();
-----오류 발생-----
let a=1;
let a=2; // 오류, 'a' has already been declared.
const b=1;
b=2; // 오류, Assignment to constant variable.
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 dafault App;
&&연산자를 사용하여 조건부 렌더링을 할 수 있다.
import React from 'react';
function App() {
const name = '뤼액트';
return <div> {name === '리액트' && <h1>리액트입니다.</h1>} </div>;
}
export dafault App;
→ false를 렌더링할 때는 null과 마찬가지로 아무것도 나타나지 않음
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 = undeinfed;
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 요소에 스타일을 적용할 때는 문자열 형태가 아니라 객체 형태로 넣어주어야 한다.
스타일 이름 중 background-color 처럼 - 문자가 포함되는 이름은 - 문자를 없애고 카멜 표기법으로 작성해야 한다.
** background-color → backgroundColor
import React from 'react';
function App(){
const name="리액트";
const style = {
backgroundColor: 'black',
fontSize: '48px',
...
};
return <div style={style}>{name}</div>;
}
export default App;
style 객체를 미리 선언하지 않고 바로 style 값을 지정하고 싶다면 다음과 같이 작성하면 된다.
function App(){
const name="리액트";
return (
<div style={{
backgroundColor: 'black',
fontSize: '48px',
...
}}
>
{name}
</div>
);
}
7) class 대신 className
일반 HTML에서 CSS 클래스를 사용할 때는 <div class="myclass"></div>와 같이 class라는 속성을 설정한다.
하지만 JSX에서는 class가 아닌 className으로 설정해주어야 한다.
import React from 'react'
import './App.css';
function App(){
const name = '리액트';
return <div className="react">{name}</div>;
}
export default App;
8) 꼭 닫아야 하는 태그
HTML 코드를 작성할 때 가끔 태그를 닫지 않은 상태로 코드를 작성하기도 한다. 예를 들면 input HTML 요소는 그냥 <input>이라고 입력해도 작동한다. 그러나 JSX는 태그를 닫지 않으면 오류가 발생하므로 태그 선언과 동시에 태그를 닫을 수 있는 <input/> 또는 <input></input>을 사용해줘야 한다.
9) 주석
JSX 내부에서 주석을 작성할 때는 {/*...*/}와 같은 형식으로 작성한다. 또 시작태그를 여러 줄로 작성할 때는 그 내부에서 //... 와 같은 형태의 주석도 사용할 수 있다.
2.5 ESLint와 Prettier 적용하기
1) ESLint
ESLint는 문법 검사 도구로, 코드를 작성할 때 실수 하면 에러 혹은 경고 메시지를 VS Code 에디터에서 바로 확인할 수 있게 해준다.
2) Prettier
Prettier은 코드 스타일 자동 정리 도구로, 들여쓰기나 제대로 되어있지 않은 문법 부분을 정리해주고커스터마이징을 통해 다양한 코드 스타일을 사전 설정할 수 있다.