티스토리 뷰

2.1 코드 이해하기

파일 > 열기 > src/App.js

 

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 구문은 특정 파일을 불러오는 것을 의미한다. 리액트로 만든 프로젝트의 자바스크립트 파일에서는 import를 사용하여 다른 파일들을 불러와 사용할 수 있다.

 

이렇게 모듈을 불러와서 사용하는 것은 사실 원래 브라우저에는 없던 기능이다. 브라우저가 아닌 환경에서 자바스크립트를 실행할 수 있게 해 주는 환경인 Node.js에서 지원하는 기능이다. 참고로 Node.js에서는 import가 아닌 require라는 구문으로 패키지를 불러올 수 있다.

 

이러한 기능을 브라우저에서도 사용하기 위해 번들러를 사용한다. 번들은 묶는다는 뜻으로 파일을 묶듯이 연결하는 것이다.

 

대표적인 번들러로 웹팩, parcel, browserify라는 도구들이 있으며, 각 도구마다 특성이 다르다. 리액트 프로젝트에서는 주로 웹팩을 사용하는 추세이다. 편의성과 확장성이 다른 도구보다 뛰어나기 때문이다. 번들러 도구를 사용하면 import(또는require)로 모듈을 불러왔을 때 불러온 모듈을 모두 합쳐서 하나의 파일을 생성해 준다. 또 최적화 과정에서 여러 개의 파일로 분리될 수도 있다.

 

2017년부터는 브라우저에서도 import 구문을 사용할 수 있게 되었지만, 이는 단순히 다른 경로에 있는 자바스크립트를 불러오는 용도로만 사용되기 때문에 프로젝트 번들링과는 다르다.

 

웹팩을 사용하면 SVG 파일과 CSS 파일도 불러와서 사용할 수 있다. 이렇게 파일들을 불러오는 것은 웹팩의 로더라는 기능이 담당한다. 로더는 여러 가지 종류가 있다. 예를 들어 css-loader는 CSS 파일을 불러올 수 있게 해 주고, file-loader는 웹 폰트나 미디어 파일 등을 불러올 수 있게 해 준다. 그리고 babel-loader는 자바스크립트 파일들을 불러오면서 최신 자바스크립트 문법으로 작성된 코드를 바벨이라는 도구를 사용하여 ES5 문법으로 변환해 준다.

최신 자바스크립트로 작성된 코드를 왜 변환하나요?
ES5는 이전 버전의 자바스크립트를 의미한다. 최신 자바스크립트 문법을 ES5 형태로 변환하는 것은 구버전 웹 브라우저와 호환하기 위해서이다. 현재 대부분의 최신 웹 브라우저에서는 자체적으로 최신 자바스크립트 문법을 바로 실행할 수 있지만, 구버전 웹 브라우저에서는 실행되지 않기 때문에 사전에 꼭 변환해 주어야 한다. 또한, 리액트 컴포넌트에서 사용하는 JSX라는 문법도 정식 자바스크립트 문법이 아니므로 ES5 형태의 코드로 변환해야 한다.

ES5 이후의 문법들은 ECMAScript 2015(ES6), ECMAScript 2016(ES7) 등과 같은 형태로 이름이 지어진다.

 

웹팩의 로더는 원래 직접 설치하고 설정해야 하지만 리액트 프로젝트를 만들 때 사용했던 crate-react-app이 번거로운 작업을 모두 대신해 주기 때문에 우리는 별도의 설정을 할 필요가 없다.

 

이 코드는 App이라는 컴포넌트를 만들어 준다. function 키워드를 사용하여 만든 컴포넌트함수 컴포넌트라고 한다. 프로젝트에서 컴포넌트를 렌더링하면(렌더링이란 '보여 준다'는 것을 의미한다.) 함수에서 반환하고 있는 내용을 나타낸다. 함수에서 반환하는 내용을 보면 마치 HTML을 작성한 듯 한데, 하지만 이 코드는 HTML이 아니다. 그렇다고 문자열 템플릿도 아니다. 이런 코드는 JSX라고 부른다.

2.2 JSX란?

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

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

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

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

만약 컴포넌트를 렌더링할 때마다 JSX 코드를 작성하는 것이 아니라 위 코드처럼 매번 React.createElement 함수를 사용해야 한다면 매우 불편할 것이다. 하지만 JSX를 사용하면 편리하게 UI를 렌더링할 수 있다.

 

JSX도 자바스크립트 문법이라고 할 수 있을까?
JSX는 리액트로 프로젝트를 개발할 때 사용되므로 공식적인 자바스크립트 문법이 아니다. 바벨에서는 여러 문법을 지원할 수 있도록 preset 및 plugin을 설정한다. 바벨을 통해 개발자들이 임의로 만든 문법, 혹은 차기 자바스크립트 문법을 사용할 수 있다.

2.3 JSX의 장점

2.3.1 보기 쉽고 익숙하다

일반 자바스크립트만 사용한 코드와 JSX로 작성한 코드를 비교하면 JSX를 사용하는 편이 가독성이 높고 작성하기도 쉽다고 느껴진다. HTML 코드를 작성하는 것과 비슷하기 때문이다. 

2.3.2 더욱 높은 활용도

JSX에서는 HTML 태그를 사용할 수 있을 뿐만 아니라, 앞으로 만들 컴포넌트도 JSX 안에서 작성할 수 있다. App.js에서는 App 컴포넌트가 만들어지는데, src/index.js 파일을 열어 보면 이 App 컴포넌트를 마치 HTML 태그 쓰듯이 그냥 작성한다.

 

ReactDOM.render는 무엇인가요?
이 코드는 컴포넌트를 페이지에 렌더링하는 역할을 하며, react-dom 모듈을 불러와 사용할 수 있다. 이 함수의 첫 번째 파라미터에는 페이지에 렌더링할 내용을 JSX 형태로 작성하고, 두 번째 파라미터에는 해당 JSX를 렌더링할 document 내부 요소를 설정한다. 여기서는 id가 root인 요소 안에 렌더링을 하도록 설정하는데, 이 요소는 public/index.html 파일을 열어보면 있다.
React.StrictMode는 무엇인가요?
React.StrictMode는 리액트 프로젝트에서 리액트의 레거시 기능들을 사용하지 못하게 하는 기능이다. 이를 사용하면 문자열 ref, componentWillMount 등 나중에는 완전히 사라지게 될 옛날 기능을 사용했을 때 경고를 출력한다.

2.4 JSX 문법 

2.4.1 감싸인 요소

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

요소 여러 개가 부모 요소 하나에 의하여 감싸져 있지 않으면 오류가 발생한다.

리액트 컴포넌트에서 요소 여러 개를 하나의 요소로 감싸주어야 하는 이유는 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는 다음과 같은 형태로도 표현할 수 있다.

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

export default App;

2.4.2 자바스크립트 표현

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

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

export default App;
ES6의 const와 let
const는 ES6 문법에서 새로 도입되었으며 한번 지정하고 나면 변경이 불가능한 상수를 선언할 때 사용하는 키워드이다. let동적인 값을 담을 수 있는 변수를 선언할 때 사용하는 키워드이다.

ES6 이전에는 값을 담는 데 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문 내부에서 새로 선언했음에도 if문 밖에서 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 = a;
let a = 2; // 오류: uncaught SyntaxError: Idenfier 'a' has already been declared.

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

const b = 1;
b = 2; // uncaught TypeError: Assignment to constant variable.

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

2.4.3 If 문 대신 조건부 연산자 (삼항연산자)

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

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

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

 

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

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

2.4.5 undefined를 렌더링하지 않기

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

 

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

 

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

2.4.6 인라인 스타일링

리액트에서 DOM 요소에 스타일을 적용할 때는 문자열 형태로 넣는 것이 아니라 객체 형태로 넣어 주어야 한다. 스타일 이름 중에서 background-color처럼 -문자가 포함되는 이름은 -을 없애고 카멜표기법으로 작성해야 한다.

2.4.7 class 대신 className

일반 HTML에서 CSS 클래스를 사용할 때는 <div class='myclass'></div>와 같이 class라는 속성을 설정한다. 하지만 JSX에서는 class가 아닌 className으로 설정해 주어야 한다.

JSX를 작성할 때 CSS 클래스를 설정하는 과정에서 className이 아닌 class 값을 설정해도 스타일이 적용되기는 하지만 브라우저 개발자 도구의 Console 탭에 경고가 나타난다.

이전에는 class로 CSS 클래스를 설정할 때 오류가 발생하고 CSS 클래스가 적용되지 않았는데, 리액트 v16 이상부터는 class를 className으로 변환시켜 주고 경고를 띄운다.

2.4.8 꼭 닫아야 하는 태그

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

예) input, br

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

코드를 저장하면 개발 서버가 실행 중인 터미널에서 오류가 나타난다.

이 오류를 해결하기 위해서는 태그를 닫아 주어야 한다.

태그 사이에 내용이 들어가지 않는 경우에는 self-closing 태그로 작성할 수도 있다. 태그를 선언하면서 동시에 닫을 수 있는 태그이다.

2.4.9 주석

JSX 안에서 주석을 작성하는 방법은 일반 자바스크립트에서 주석을 작성할 때와 조금 다르다.

import './App.css';

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

export default App;

JSX 내부에서 주석을 작성할 때는 {/*...*/}와 같은 형식으로 작성한다. 이렇게 여러줄로 작성할 수도 있다. 그리고 시작 태그를 여러 줄로 작성할 때는 그 내부에서 // ...와 같은 형태의 주석도 작성할 수 있다.

 

만약 일반 자바스크립트에서 주석을 작성할 때처럼 아무 데나 주석을 작성하면 그 주석은 페이지에 고스란히 나타난다.

2.5 ESLint와 Prettier 적용하기

2.5.1 ESLint

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

ESLint는 코드를 작성할 때 실수를 하면 에러 혹은 경고 메시지를 VS Code 에디터에서 바로 확인할 수 있게 해준다.

에디터 하단에 뜨는 문제 탭은 VS Code의 상단 메뉴에서 보기>문제를 클릭하여 열 수 있다.

에디터에 초록색 줄이 그어진 코드는 고치기 싫다면 무시해도 되지만 빨간색 줄이 그어진 코드는 반드시 고쳐야 한다.이런 오류는 고치지 않으면 페이지가 브라우저에 나타나지 않는 치명적인 오류이므로 꼭 고쳐주어야 한다.

2.5.2 Prettier

JSX를 작성할 때는 코드의 가독성을 위해 들여쓰기를 사용한다. 들여쓰기가 제대로 되어있지 않은 코드는 읽기가 매우 힘들기 때문이다.

VS Code에서 f1을 누르고 format이라고 입력한 다음 Enter를 누른다.

Prettier를 사용하여 자동 코드 정리를 하면 코드가 제대로 정렬되고, 세미콜론(;)이 빠진 곳에는 세미콜론이 자동으로 추가되고, 기존에 사용하던 작은따옴표는 모두 큰따옴표로 바뀐다.

 

자바스크립트에서는 문자열을 표현할 때 작은따옴표를 써도 되고 큰따옴표를 써도 된다. 세미콜론은 코드의 뒷부분에 무조건 있어야 하는 문자가 아니다. 이는 단순히 코딩 관습의 차이이고 주로 협업하는 과정에서 정하는 규칙이고, 사람들마다 다른 방식을 사용한다.

 

Prettier의 장점은 이러한 스타일을 쉽게 커스터마이징할 수 있다는 것이다. 현재 열려있는 프로젝트의 루트 디렉터리(src, public 디렉터리들이 위치한 곳)에서 .prettierrc라는 파일을 생성한 후 내용을 입력한다.

https://prettier.io/docs/en/options.html

2.5.2.1 저장할 때 자동으로 코드 정리하기

코드 스타일 정리할 필요가 있을 때마다 f1을 누른 후 Fomat을 입력하는 것보다, 혹은 단축키를 입력하는 것보다 더 편한 방식은 저장할 때 자동으로 정리하게 만드는 것이다.

VS Code 설정

Code(윈도우의 경우 파일) > 기본 설정 > 설정 메뉴 클릭

다음으로 상단 텍스트 박스에서 format on save를 검색하여 나타나는 체크박스에 체크한다.

이제부터는 저장할 때마다 코드가 자동으로 정리된다.

2.6 정리

JSX는 HTML과 비슷하지만 완전히 똑같지는 않다. 코드로 보면 XML 형식이지만 실제로는 자바스크립트 객체이며, 용도도 다르고 문법도 조금씩 차이가 난다. 

 

 

 

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함