Components 란?

React는 사용자 인터페이스를 더 쉽게 구축하기 위하 자바스크립트 라이브러리 입니다. 그런데 사용자 인터페이스는 컴포넌트로 구성되어집니다. 그렇다면 이 컴포넌트라는 것은 어떤 것일까요?

위 사진의 간단한 어플리케이션에서 살펴보면 컴포넌트라는 것은 사용자 인터페이스의 구성요소에서 반복되며 재사용가능한 html, css, javascript로 만들어진 블록을 의미합니다.

이러한 재사용 가능한 블록들을 조합하여 사용자 인터페이스를 만들게됩니다. 이구조는 두가지 큰 이점을 가져다 줍니다.

  • 재사용 가능성 : 클린코드에서도 중요한 개념인 Dry한 코드를 하게 합니다. 반복을 하지 않음으로서 코드크기를 줄이고 보다 관리가 용이한 코드를 만들어줍니다.
  • Seperation of Concerns : SOC라고 부르는 개념입니다. 관심사를 분리하여 각각의 관심사 별로 이슈를 해결하고 보다 관심사에 대해서 자유롭게 분석 분리등을 할수 있습니다. 이는 각각의 개별요소를 좀더 재사용성이 높게 디자인 할수 있습니다. 이는 한 관심사에 너무 많은 요소들이 들어가지 않게 합니다.

리액트는 컴포넌트를 사용함으로서 선언적인 코드 사용방식을 가져갑니다. 컴포넌트를 선언하거나 함수를 선언함으로서 해당 코드를 재사용하는 방식입니다.

React 프로젝트를 시작하는 가장 기본적인 방법 : Create - React - App

위 방법을 사용하는 이유는 프로젝트를 만들자 마자 바로 돌아가는 빌트인 웹페이지가 있으며 코드를 수정하면 바로 브라우저에 수정코드가 반영되는 react-hot-loader 같은 기능을 내장하고 있기 때문에 webpack, babel 설정을 따로 안해줘도 됩니다.

단지, 프로젝트 시작시 프로세스를 최소화하기위한 방법으로서 CRA를 사용합니다.

create react app

위 과정을 통해서 react 앱을 만들수 있습니다.

React 프로젝트 분석

src

src 폴더는 코드를 짜는데 있어 가장 많은 시간을 보내는 곳입니다. 이안에 들어있는 코드들은 React로 작업하는 파일들입니다. 특별한 React 구문들을 사용하지만 결국에는 JavaScript 일 것 입니다.

index.js


가장 첫번째 코드입니다. 페이지가 로딩될때 가장 먼저 실행되는 파일입니다. 하지만 브라우저에서 위와같이 파일이 동작하는 것은 아닙니다. 브라우저 동작과정을 거치기 전에 npm start 프로세스는 React 구문들을 브라우저에서 파싱가능할 언어들로 변환 해줍니다.

예를 들면 import '/index.css' 라는 구문은 일반적인 JS에서는 통용되지 않은 문법입니다. 하지만 npm 프로세스가 중간 변환을 거쳐 브라우저에 전달해주기 때문에 위 코드가 문제가 없는 것입니다.

JSX

ReactDOM.render(<App />, document.get...));
위 코드에서 <App / > 이라는 표현은 일반적인 JS에서는 사용하지 못합니다. JS안에 html 문법이 들어가 있기 때문입니다. 이 또한 npm 프로세스가 변환과정을 거쳐 브라우저가 이해가능할 언어들로 변환해주어 전달하기 때문에 문제가 없습니다.

import ReactDOM from 'react-dom'

react-dom 이라는 패키지에서 부터 ReactDOM 이라는 컴포넌트를 해당 코드가 적힌 파일로 가져온다는 뜻입니다. react-dom 은 React 프로젝트 의 내장 패키지로서 react 내장 패키지와 더불어 React 라이브러리를 구성합니다.

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

render 함수는 두개의 인수를 받습니다. 두번째 인수는 JS DOM API 함수로서 DOM 객체를 받습니다. 이 DOM 객체는 root 라는 아이디를 지닌 DOM 으로서 해당 파일을 찾아보면

public 이라는 폴더 안에 index.html 파일안에서 찾아 볼수 있습니다.
<div id='root'></div>이 DOM의 내용은 아무것도 없습니다.

즉, render 함수는 이 DOM 안에 <App/> 을 렌더링 하고 싶다는 이야기 입니다.

그렇다면 <App/>이라는 것은 무엇일까요 ? index.js 파일에 보면 import App from './App.js' 라는 코드가 있습니다.

src 폴더의 App.js 에서 가져왔다는 표현이 됩니다.

JSX

위 코드에서 render(<App/>, ...) 이런 표현은 사실 JS에서 사용할수 없는 표현입니다. 자바스크립트와 html 문법이 같이 쓰이는 형태를 JSX라고 부르기로 하고 React 개발자들이 만들어 냈습니다.

JSX는 JavaScriptXML의 준말입니다. 결국 HTML은 XML이기 때문에 이러한 이름이 만들어지게 되었습니다. npm start 프로세스가 이러한 JSX를 순 JS로 만들고 브라우저 친화적인 코드로 변경되어 동작하기 때문에 가능합니다. 실제로 브라우저에서 동작하는 코드를 살펴봅시다.

XML은 Html과 같이 마크업 언어의 일종입니다. 하지만 XML은 태그를 사용자가 지정해서 만들수 있습니다. 데이터를 교환하는 것을 목적으로 만들어진 마크업 언어입니다. XML은 어떠한 데이터를 새로운 이름을 가진 태그로 묶어두는 역할을 한다라고 생각하면 됩니다.

브라우저의 개발자 모드로 들어가서 보면 chuck, bundle.js등등의 파일들이 있는 가운데 main.chuck.js안에 function App() 이 보입니다. 위 사진에서 보았던 function App과는 굉장히 다르게 생겼습니다. 이렇게 코드가 브라우저에서 읽을 수 있는 코드로 변경이 되었습니다.

  const content = document.getElementById("root");
  const para = document.createElement("p");
  para.textContent = "Wow this is traditional JS";
  content.append(para);

위 와 같은 과정은 실시간으로 DOM에 접근함으로서 DOM을 생성하고 추가하고 만들고 하는 과정들을 만들어 냄으로서 굉장히 귀찮고 복잡한 코드를 작성해야합니다.

function App() {
  
  return (
    <div>
      <h2>Let's get started!</h2>
    </div>
  );
}
export default App;

하지만 위와 같은 함수형 반환을 이용한 React의 JSX를 사용하면 원하는 최종상태를 정의하여 반환함으로서 훨씬 간결한 코드를 보여줄 수 있습니다.

JSX에 표현식 포함

JSX에는 변수로 선언한 값을 중괄호안에 넣어 DOM에 추가할 수 있습니다. 표현식은 값을 가지는 변수로서 값을 반환하는 것은 표현식이라고 할수 있습니다. JSX 자체도 표현식입니다. return() 안에서 하나의 JSX로 반환됩니다.

import "./ExpenseItem.css";
export default function ExpenseItem() {
  const date = new Date(2021, 3, 28);
  return (
    <div className="expense-item">
      <div>{date.toISOString().slice(0, 10)}</div>
      <div className="expense-item__description">
        <h2>Car Insurace</h2>
        <div className="expense-item__price">$294.45</div>
      </div>
    </div>
  );
}

❗️ 이러한 특성으로 react로 만든 jsx를 사용하면 사용자의 주입식 공격 XSS (Cross site scripting) 에 안전합니다. JSX 내의 모든 표현식 삽입은 명시적으로 선언된 변수들이 렌더링 되기전에 모두 문자열로 변환되어 렌더링되기 때문에 사용자가 실시간으로 데이터를 주입할 수가 없습니다. 표현식 삽입은 개발자가 명시적으로 선언한 부분들만 가능합니다.

JSX를 안쓴다면?

React 에서 JSX를 안쓴다면 어떻게 될까? JSX는 리액트에서 지원하는 문법으로서 이러한 JSX의 기능을 상세히 알려면 JSX를 안쓰고 같은 기능을 하는 코드를 짜보면 된다.

  return (
    <div>
      <h2>Let's get started!</h2>
      <ExpenseItem items={expense}/>
    </div>
  );

  return React.createElement(
    "div",
    {},
    React.createElement("h2", {}, "Let's get started!"),
    React.createElement("ExpenseItem", { items: expense })
  );       

위 두개의 코드는 하는 기능이 같습니다만, 가독성 부분에서 거대한 차이가 있습니다. JSX는 결국에 아래코드의 형태로 변환이되고 브라우저 언어로 변환되게 되어있습니다.

  • 아래 React.createElement 에서 가장 위에 있는 루트 element 하나만이 반환됩니다. 따라서 jsx에서도 두가지의 태그를 반환하는 것이 아니라 루트 태그만을 반환 할수 있습니다.

  • 또한 <>...</> 이렇게 이름없는 태그로 묶어서 반환도 가능한데 이또한 React.createElement에서 첫 인수로 "" 문자열이 아얘없는 것으로 들어가도 되기 때문입니다.

profile
일상을 기록하는 삶을 사는 개발자 ✒️ #front_end 💻

0개의 댓글