본문 바로가기

4. Node.js | React.js

4/22(토) IT K-DT(-) / 1.react.js개요~5. 엘리멘트 렌더링

0. react.js에 들어가기 전

1. react.js의 개요

2. react.js의 특징

    2-1. 단방향 Data Flow

    2-2. Component 기반 구조

    2-3. Virtual DOM을 사용

    2-4. Props and State를 사용

    2-5. JSX를 사용

3. react.js의 형식

4. JSX

    4-1. JSX에 표현식 포함

    4-2. JSX 속성 정의

5. 엘리멘트 렌더링

    5-1. DOM에 엘리먼트 렌더링하기

    5-2. 렌더링 된 엘리먼트 업데이트하기

    5-3. 변경된 부분만 업데이트하기

 

0. react.js에 들어가기 전

* react.js 교육 간 사용할 에디터 : Visual Studio Code

교육에 사용할 폴더를 드래그해서 바탕화면 아이콘에 드롭하여 실행.

 

교육 간 참고할 이론:

(https://ko.legacy.reactjs.org/)

 

React – 사용자 인터페이스를 만들기 위한 JavaScript 라이브러리

A JavaScript library for building user interfaces

ko.legacy.reactjs.org

 

교육 간 참고할 동영상:

https://www.youtube.com/watch?v=6GECT2Jrr_g 

 

* react 사용 방법

 

1. HTML 파일에 react 링크를 삽입하는 방법.

1-1. HTML의 </body> 바로 앞에 react.js javascript CDN을 적용.

HTML


<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>React CDN 추가</title>
    </head>

    <body>

        <div></div>

....

  <!-- 주의: 사이트를 배포할 때는 "development.js"를 "production.min.js"로 대체 -->
  <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>

    </body>
</html>

 

1-2. react가 발현될 <div>를 지정.

    보통은 id="root"를 많이 사용하나, 어떤 것을 사용해도 무방함.

    id를 설정한 이후, script 태그 내부에 react 문을 작성.

    (react도 JavaScript이므로 JavaScript 형식으로 작성해야 함)

 

    ReactDOM.render(A, B)

    : 'A'를 'B'에 표시.


    React.createElement(A, B, C) 

: 'A 태그'를 'B의 속성' + 'C의 내용'을 넣어서 DOM을 생성.

HTML

...

<body>
         react가 나타날 위치 
     <div id="root"></div>

     <script type="text/javascript">
            // react가 나타날 위치에 h1 태그를 생성
            ReactDOM.render ( React.createElement( "h1", { style: { color: "blue" } }, "안녕하세요." ), 
            document.getElementById("root") ) ;
     </script>

     <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
     <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>

    </body>

(출처: https://ux.stories.pe.kr/298)

 

2. 별도의 react 컴포넌트 파일을 만들어 링크하는 방법.

2-1. HTML의 </body> 바로 앞에 react.js javascript CDN을 적용.

HTML


<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>React CDN 추가</title>
    </head>

    <body>

        <div></div>

....

  <!-- 주의: 사이트를 배포할 때는 "development.js"를 "production.min.js"로 대체 -->
  <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>

  <!-- 만든 React 컴포넌트를 실행. -->
  <script src="like_button.js"></script>

    </body>
</html>

 

2-2. 'like_button.js' 라는 파일을 새로 생성

JavaScript


'use strict';

const e = React.createElement;

class LikeButton extends React.Component {
  constructor(props) {
    super(props);
    this.state = { liked: false };
  }

  render() {
    if (this.state.liked) {
      return 'You liked this.';
    }

    return e(
      'button',
      { onClick: () => this.setState({ liked: true }) },
      'Like'
    );
  }
}

2-1에서 HTML 페이지에 추가했던 <div> 태그를 찾아주고, 해당 태그에 React 앱을 만들어주고,
그 안에 “좋아요” 버튼 React 컴포넌트를 추가
const domContainer = document.querySelector('#like_button_container');
const root = ReactDOM.createRoot(domContainer);
root.render(e(LikeButton));

 

3. package를 다운로드하는 방법

 

명령 프롬프트에서 ' npm i react-router-dom ' 을 입력.

 

 

1. react.js의 개요

오픈소스의 JavaScript 라이브러리.


프론트엔드 개발자 사이에서 Angular.js, Vue.js와 더불어 많은 인기를 얻고 있음.

Github Star의 수와 npm 패키지 다운로드 수가 가장 많음.

동적인 모던 웹에서 엄청나게 빠른 퍼포먼스를 낼 수 있음.

모듈형 개발이기 때문에 생산성이 높은 라이브러리이며, 다른 프레임워크에 간편하게 붙여서 사용하는 것도 가능.

사실상 웹 프론트엔드 개발의 표준으로 자리잡음.

 

 

(출처: https://namu.wiki/w/React(%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC))

 

2. react.js의 특징

 

2-1. 단방향 Data Flow

React는 데이터의 흐름이 한 방향으로만 흐르는 단방향 데이터 흐름을 가짐.
양방향 데이터 흐름(= Augular.js)은 규모가 커질수록 흐름을 추적하기가 힘들고 복잡해지는 경향이 있음

→ 복잡한 앱에서도 데이터 흐름에서 일어나는 변화를 쉽게 예측 가능할 수 있도록 함.

 


2-2. Component 기반 구조

Component는 '독립적인 단위의 소프트웨어 모듈'을 말함.
즉, SW를 독립적인 하나의 부품으로 만드는 방법.

React는 UI(View)를 여러 컴포넌트(component)를 쪼개서 만든 것.
한 페이지 내에서도 여러 각 부분을 독립된 컴포넌트로 만들고, 이 컴포넌트를 조립해 화면을 구성.

컴포넌트 단위로 쪼개져 있기 때문에, 전체 코드의 파악이 상대적으로 쉽고,

기능 단위, UI 단위로 캡슐화시켜 코드를 관리하기 때문에 재사용성이 높음.

따라서 코드는 반복 입력할 필요 없이 컴포넌트만 import해 사용하면 된다는 간편함이 있으며,

애플리케이션이 복잡해지더라도 코드의 유지보수, 관리가 용이해지는 장점을 가짐.

 

예)


class App extends Component {

  render() {
    return (

      <Layout>
        <Header />
        <Navigation />

        <Content>
          <Sidebar></Sidebar>
          <Router />
        </Content>

        <Footer></Footer>
      </Layout>

    );
  }
}

위와 같이 Header, Footer같은 구조는 컴포넌트로 만들고, 이를 조합해서 root component를 만드는 방식.

 


2-3. Virtual DOM을 사용

DOM은 Document Object Model의 약자로,

HTML, XML, CSS 등을 트리 구조로 인식, 데이터를 객체로 간주하고 관리하는 모델임.


React는 이 DOM과 같은 구조체를 Virtual DOM(가상 DOM)으로 가지고 있음.


React DOM

가상 돔(Virtual DOM). React 라이브러리와 함께 제공되는, 브라우저 DOM과 상호작용하기 위한 도구 모음.
React DOM은 React 앱을 HTML 페이지에 렌더링하고, 이벤트 처리 및 상태 업데이트 등의 작업을 처리.

React DOM은 React 앱의 Virtual DOM을 생성하고, 이를 브라우저 DOM에 동기화함.
Virtual DOM은 React 앱의 상태 및 프로퍼티 변경 등 업데이트를 추적하고, 이에 따라 렌더링을 업데이트함. 이를 통해 React DOM은 빠르고 효율적인 UI 렌더링을 가능하게 함.

React DOM은 ReactDOM 모듈을 통해 제공됨.

이 모듈에는 React 앱을 렌더링하고 관리하는 데 사용되는 여러 가지 함수와 메서드가 포함되어 있음.
예를 들어, ReactDOM.render() 함수는 React 앱을 초기화하고 렌더링하는 데 사용되며, ReactDOM.createRoot() 함수는 React 18에서 추가된 새로운 루트 API를 생성함.

React DOM은 브라우저 뿐만 아니라, React Native 등의 다른 환경에서도 사용될 수 있음. 다양한 플랫폼에서 React 앱을 구축하고 렌더링하기 위해 React DOM 대신 다른 도구 모음을 사용할 수도 있음.


이벤트가 발생할 때마다 Virtual DOM을 생성 → 다시 그릴 때마다 실제 DOM과 실시간으로 비교 가능.

앱의 효율성과 속도를 개선.

 

(출처: https://dev-cini.tistory.com/11)

 

2-4. Props and State를 사용

Props
Props란 '부모 컴포넌트에서 자식 컴포넌트로 전달해 주는 데이터'를 의미.
자식 컴포넌트에서 전달받은 props는 변경이 불가능하고

전달해준 최상위 부모 컴포넌트만 props를 변경할 수 있음. (='읽기 전용 데이터')

State
State는 컴포넌트 내부에서 선언하며 '내부에서 값을 변경할 수 있는 상태값'을 의미.

동적인 데이터를 다룰 때 사용하며,외부요소와의 상호작용을 통해 데이터를 동적으로 변경할 때 사용.

컴포넌트를 클래스나 함수로 작성할 때 사용할 수 있고, 각각의 state는 독립적인 특성을 가짐.

 

클래스형 컴포넌트에서 State를 사용할 때는 다음과 같은 순서로 사용함.
    1. constructor 메서드에서 this.state를 사용하여 초기화.
    2. 상태값을 변경: this.setState 메서드를 사용.
    3. 상태값을 참조: this.state 메서드를 사용.


2-5. JSX를 사용

JavaScript를 확장한 문법으로, React에서 UI를 작성하기 위해 사용.

JavaScript 코드 내부에서 HTML과 같은 MarkUp 언어를 사용할 수 있어

UI를 렌더링하는 코드를 작성할 때 직관적이고 간결하게 작성할 수 있음.

JSX 코드는 일반적으로 .jsx 확장자를 가진 파일에 작성하며,

React에서 제공하는 ReactDOM.render() 함수를 사용하여 렌더링할 컴포넌트를 지정하면 됨.

JSX 사용은 React에서 필수가 아니지만, 대부분 JavaScript 코드 안에서 UI 관련 작업을 할 때 사용.

 

 

(출처: https://velog.io/@jini_eun/React-React.js%EB%9E%80-%EA%B0%84%EB%8B%A8-%EC%A0%95%EB%A6%AC)

 

 

3. react.js의 형식

예) 'Hello, world!'를 출력하는 react.js의 가장 기본적인 형식


const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(<h1>Hello, world!</h1>);

 

ReactDOM.createRoot( '찾을요소' )

React 앱을 렌더링하는 데 사용.

React 컴포넌트 트리를 마운트하고 갱신하는 데 필요한 내부 데이터 구조를 만듦.

 

root.render( '내용' )

해당 내용의 컴포넌트를 갖는 React 앱의 초기 렌더링을 시작하거나,

이후에 상태나 프로퍼티가 변경될 때 다시 렌더링을 트리거함.

 

4. JSX

 

4-1. JSX에 표현식 포함

예) 'name'이라는 변수를 선언한 후 JSX를 이용하여 'element'라는 변수를 선언하는데 이용


const name = 'Josh Perez';
const element = <h1>Hello, {name}</h1>;

JSX의 중괄호 안에는 유효한 모든 JavaScript 표현식을 넣을 수 있음. 

 

예) formatName(user)을 JSX를 이용하여 <h1>에 포함


function formatName(user) {
  return user.firstName + ' ' + user.lastName;
}

const user = {
  firstName: 'Harper',
  lastName: 'Perez'
};

const element = (
  <h1>
    Hello, {formatName(user)}!
  </h1>
);

컴파일이 끝나면, JSX 표현식이 정규 JavaScript 함수 호출이 되고 JavaScript 객체로 인식됨.

→  JSX를 if문 및 for loop에 사용하고, 변수에 할당하고, 인자로서 받아들이고, 함수로부터 반환할 수 있음.


function getGreeting(user) {
  if (user) {
    return <h1>Hello, {formatName(user)}!</h1>;
  }
}

 

4-2. JSX 속성 정의

attribute에 따옴표(' ')를 이용해 문자열 리터럴을 정의할 수 있음.
예)


const element = <a href="https://www.reactjs.org"> link </a>;

 

중괄호를 사용하여 attribute에 JavaScript 표현식을 삽입할 수도 있음.

예)


const element = <img src= { user.avatarUrl } ></img>;

attribute에 JavaScript 표현식을 삽입할 때 중괄호 주변에 따옴표를 입력할 수 없음.

따옴표(문자열 값에 사용) 또는 중괄호(표현식에 사용) 중 하나만 사용해야 함.

→ 동일한 attribute에 두 가지 옵션을 동시에 사용할 수 없음.

JSX는 HTML보다는 JavaScript에 가깝기 때문에,

React DOM은 HTML attribute 이름 대신 camelCase 프로퍼티 명명 규칙을 사용.
예를 들어, JSX에서 class는 className가 되고 tabindex는 tabIndex가 됨.

 

태그가 비어있다면 XML처럼 /> 를 이용해 바로 닫아주어야 함.
예)


const element = <img src={user.avatarUrl} />;

 

JSX 태그는 자식을 포함할 수 있음.
예)


const element = (
  <div>
    <h1>Hello!</h1>
    <h2>Good to see you here.</h2>
  </div>
);


JSX는 주입 공격을 방지 → JSX에 사용자 입력을 삽입하는 것은 안전함.


const title = response.potentiallyMaliciousInput;
// 문제 없음.


const element = <h1>{title}</h1>;
기본적으로 React DOM은 JSX에 삽입된 모든 값을 렌더링하기 전에 이스케이프함.
애플리케이션에서 명시적으로 작성되지 않은 내용은 주입되지 않음.

모든 항목은 렌더링 되기 전에 문자열로 변환.

이런 특성으로 인해 XSS (cross-site-scripting) 공격을 방지할 수 있음.

JSX는 객체를 표현함.
예) 동일한 두 예시


const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);


const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);

 

5. 엘리멘트 렌더링

React 엘리먼트를 실제 브라우저 DOM 노드로 렌더링(시각적으로 출력)하는 과정.

 

엘리멘트(Element)

React 앱의 가장 작은 단위로, 화면에 표시할 내용을 기술함.


const element = <h1>Hello, world</h1>;


리액트 엘리멘트(React Element)

화면에서 보고 싶은 것을 나타내는 단순화된 구조의 표현. 아래와 같은 예시의 객체.

React는 이 객체를 읽어서, DOM을 구성하고 최신 상태로 유지하는 데 사용.


const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Hello, world!'
  }
};

브라우저 DOM 엘리먼트와 달리 React 엘리먼트는 일반 객체이며(plain object), 쉽게 생성할 수 있음.

React DOM은 React 엘리먼트와 일치하도록 DOM을 업데이트함.

 

“컴포넌트”와 엘리먼트를 혼동할 수 있음. 엘리먼트는 컴포넌트의 “구성 요소”이므로 혼동하지 않도록 주의.

 

5-1. DOM에 엘리먼트 렌더링하기

HTML 파일 어딘가에 <div>가 있다고 가정해보자.


  <div id="root"></div>

모든 내부의 엘리먼트를 React DOM에서 관리하기 때문에 위의 <div>를 “루트(root) DOM 노드"라 부름.

React로 구현된 애플리케이션은 일반적으로 1개의 루트 DOM 노드가 있음. 

React를 기존 앱에 통합하려는 경우, 많은 수의 독립된 루트 DOM 노드가 있을 수 있음.

React 엘리먼트를 렌더링 하기 위해서는 

    1. 우선 DOM 엘리먼트를 ReactDOM.createRoot()에 전달한 다음, 

    2. React 엘리먼트를 root.render()에 전달해야 함.

 

예) 화면에 'Hello World'가 출력


const root = ReactDOM.createRoot(document.getElementById('root'));

const element = <h1>Hello, world</h1>;
root.render(element);

 

5-2. 렌더링 된 엘리먼트 업데이트하기

React 엘리먼트는 '불변객체'로, 엘리먼트를 생성한 이후에는 해당 엘리먼트의 자식/속성을 변경할 수 없음.

엘리먼트는 영화에서 하나의 프레임과 같이 '특정 시점의 UI'를 보여줌.

UI를 업데이트하는 유일한 방법: 새로운 엘리먼트를 생성 후 root.render()로 전달.

예) setInterval() 콜백을 이용해 초마다 root.render()를 호출하는 시계.


const root = ReactDOM.createRoot(
  document.getElementById('root ')
);

function tick() {

  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );

  root.render(element );
}

setInterval(tick, 1000);

실제로 대부분의 React 앱은 root.render()를 한 번만 호출함.

 

toLocaleTimeString()

로컬 시간에 따라 Date 객체의 시간 부분을 문자열로 반환.

 

5-3. 변경된 부분만 업데이트하기

React DOM은 이전의 엘리먼트와 비교하여 필요한 경우에만 DOM을 업데이트함.