관리 메뉴

거니의 velog

(8) 컴포넌트 1 본문

React_리액트 시작

(8) 컴포넌트 1

Unlimited00 2023. 11. 29. 15:26

* 리액트를 사용하여 애플리케이션의 인터페이스를 설계할 때 사용자가 볼 수 있는 요소는 여러 가지 컴포넌트로 구성되어 있다. 예를 들어 뒤에서 만들어 볼 일정 관리 애플리케이션을 미리 살펴보자.

* 위 프로젝트는 총 네 가지 컴포넌트를 사용하여 구성했다. 먼저 전체적인 틀을 잡아 주는 TodoTemplate 컴포넌트이다. 이 컴포넌트는 현재 화면의 중앙에 있는 사각형 레이아웃의 역할을 하고 있다. 그리고 새로운 항목을 추가할 수 있는 TodoInput 컴포넌트이다. 위 화면에서는 검정색 영역이 바로 TodoInput이다. 그리고 할 일 항목을 여러 개 보여 주는 TodoList 컴포넌트이다. 마지막으로 TodoList에서 각 항목을 보여 주기 위해 사용되는 TodoItem 컴포넌트이다.

* 컴포넌트의 기능은 단순한 템플릿 이상이다. 데이터가 주어졌을 때 이에 맞추어 UI를 만들어 주는 것은 물론이고, 라이프사이클 API를 이용하여 컴포넌트가 화면에서 나타날 때, 사라질 때, 변화가 일어날 때 주어진 작업들을 처리할 수 있으며, 임의 메서드를 만들어 특별한 기능을 붙여줄 수 있다.

* 이번에는 먼저 클래스형 컴포넌트에 대해 살펴본 뒤, 컴포넌트를 새로 만들고 사용하는 방법을 알아보자. 그리고 컴포넌트의 속성 값을 지닌 props와 상태 값을 지닌 state를 사용하는 방법도 알아보자.


1. 클래스형 컴포넌트

* 이전에 보았던 App 컴포넌트는 함수형 컴포넌트이며, 코드가 다음과 같은 구조로 이루어져 있다.

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

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

export default App;

* 컴포넌트를 선언하는 방식은 두 가지이다. 하나는 함수형 컴포넌트이고, 또 다른 하나는 클래스형 컴포넌트이다.

* 클래스형 컴포넌트가 어떻게 이루어졌는지 확인해 보자. App.js 코드를 한 번 다음과 같이 수정해 보자.

import React, { Component } from 'react';
import './App.css';

class App extends Component {
  render() {
    const name = 'react';
    return <div className="react">{name}</div>;
  }
}

export default App;

* 클래스형 컴포넌트로 바뀌었지만 역할은 이전에 보았던 함수형 컴포넌트와 똑같다. 클래스형 컴포넌트와 함수형 컴포넌트의 차이점은 클래스형 컴포넌트의 경우 이후 배울 state 기능 및 라이프사이클 기능을 사용할 수 있다는 것과 임의 메서드를 정의할 수 있다는 것이다.

* ES6의 클래스 문법

- ES6 이전에는 자바스크립트에 클래스(class)가 없었다. 개념 자체는 있었지만, 그것을 구현하려면 class 대신에
  prototype이라는 문법을 사용하여 다음과 같이 작업해야 했다.
  
function Dog(name) {
	this.name = name;
}

Dog.prototype.say = function(){
	console.log(this.name + ': 멍멍');
}

var dog = new Dog('검둥이');
dog.say(); // 검둥이: 멍멍

- ES6 문법부터는 이것과 기능이 똑같은 코드를 class로 사용하여 다음과 같이 작성할 수 있다.

class Dog {
	constructor(name) {
    	this.name = name;
    }
    say() {
    	console.log(this.name + ': 멍멍');
    }
}

const dog = new Dog('흰둥이');
dog.say(); // 흰둥이: 멍멍

* 클래스형 컴포넌트에서는 render 함수가 꼭 있어야 하고, 그 안에서 보여 주어야 할 JSX를 반환해야 한다.

* 컴포넌트를 선언할 수 있는 두 가지 방법 중 어느 상황에 함수형 컴포넌트를 사용해야 할까?

* 함수형 컴포넌트의 장점을 나열해 보면 다음과 같다. 우선 클래스형 컴포넌트보다 선언하기가 훨씬 편하다. 메모리 자원도 클래스형 컴포넌트보다 덜 사용한다. 또한, 프로젝트를 완성하여 빌드한 후 배포할 때도 함수형 컴포넌트를 사용하는 것이 결과물의 파일 크기가 더 작다. 
(다만, 함수형 컴포넌트와 클래스형 컴포넌트는 성능과 파일 크기 면에서 사실상 별 차이가 없으므로 이 부분은 너무 중요하게 여기지 않아도 된다)

* 함수형 컴포넌트의 주요 단점은 state와 라이프사이클 API의 사용이 불가능하다는 점이다. 이 단점은 리액트 v16.8 업데이트 이후 Hooks라는 기능이 도입되면서 해결되었다. 완전히 클래스형 컴포넌트와 똑같이 사용할 수 있는 것은 아니지만 조금 다른 방식으로 비슷한 작업을 할 수 있게 되었다. 이번에는 Hooks에 대한 내용은 맛보기만 조금 배워 보고, 나중에 더 자세히 다루겠다.

* 리액트 공식 메뉴얼에서는 컴포넌트를 새로 작성할 때 함수형 컴포넌트와 Hooks를 사용하도록 권장하고 있다. 하지만 그렇다고 해서 클래스형 컴포넌트가 사라지는 것은 아니므로 클래스형 컴포넌트의 기능은 꼭 알아두어야 한다.

* 우리는 초반부에서 기능을 구현할 때 클래스형 컴포넌트 위주로 사용하여 리액트의 기본기를 익히고, 후반부에서 Hooks를 완벽히 이해한 후 함수형 컴포넌트와 Hooks를 기반으로 컴포넌트를 작성할 것이다.


2. 첫 컴포넌트 생성

* 첫 번째 컴포넌트를 만들어 보자.


(1) src 디렉터리에 MyComponent.js 파일 생성

* 컴포넌트를 만들려면 컴포넌트 코드를 선언해야 한다. 컴포넌트 코드를 선언할 파일을 만들어 보자. VS Code 왼쪽 사이드바에 있는 파일 목록 중 src 디렉터리를 마우스 오른쪽 버튼으로 누른 후 새 파일 메뉴를 선택하자.

* 새 파일 이름을 입력하는 칸이 나타나면 MyComponent.js라고 입력하자.


(2) 코드 작성하기

* MyComponent.js 파일을 열고 새 컴포넌트의 코드를 작성해 보자. 먼저 함수형 컴포넌트로 작성하고, 나중에 클래스형 컴포넌트로도 작성해 보자.

import React from 'react';

const MyComponent = () => {
  return <div>나의 새롭고 멋진 컴포넌트!</div>;
};

export default MyComponent;

* 이번에 작성한 코드는 이전에 보았던 App 컴포넌트와 형태가 조금 다르다. 함수를 작성할 때 function 키워드를 사용하는 대신에 () => { } 를 사용하여 함수를 만들어 주었다. 이는 ES6에 도입된 화살표 함수 문법이다.

< ES6의 화살표 함수 >

* 화살표 함수(arrow function)는 ES6 문법에서 함수를 표현하는 새로운 방식이다. 그렇다고 해서 기존 function
  을 이용한 함수 선언 방식을 아예 대체하지는 않는다. 사용 용도가 조금 다를 뿐이다. 이 문법은 주로 
  함수를 파라미터로 전달할 때 유용하게 사용된다.
  
setTimeout(function(){
	console.log('Hello World');
}, 1000);

setTimeout(() => {
	console.log('Hello World');
}, 1000);

----------------------------------------------------------------------------

* 이 문법이 기존 function을 대체할 수 없는 것은 용도가 다르기 때문이다.
  무엇보다 서로 가리키고 있는 this의 값이 다르다.
  
  다음 코드를 한 번 확인해 보자.
  
function BlackDog() {
	this.name = '흰둥이';
    return {
    	name : '검둥이',
        bark : function() {
        	console.log(this.name + ': 멍멍!');
        }
    }
}

const blackDog = new BlackDog();
blackDog.bark(); // 검둥이: 멍멍!

function WhiteDog() {
	this.name = '흰둥이';
    return {
    	name : '검둥이',
        bark : () => {
        	console.log(this.name + ': 멍멍!');
        }
    }
}

const whiteDog = new WhiteDog();
whiteDog.bark(); // 흰둥이: 멍멍!

function()을 사용했을 때는 검둥이가 나타나고, () => 를 사용했을 때는 흰둥이가 나타난다.
일반 함수는 자신이 종속된 객체를 this로 가리키며, 화살표 함수는 자신이 종속된 인스턴스를 가리킨다.

----------------------------------------------------------------------------
* 화살표 함수는 값을 연산하여 바로 반환해야 할 때 사용하면 가독성을 높일 수 있다.

function twice(value) {
	return value = 2;
}

const triple = (value) => value * 3;

이렇게 따로 { }을 열어주지 않으면 연산한 값을 그대로 반환한다는 의미이다.

* 함수형 컴포넌트를 선언할 때 function 키워드를 사용하는 것과 화살표 함수 문법을 사용하는 것 간에는 큰 차이가 없다. 화살표 함수를 사용하는 것이 더 간결하기 때문에 여기서는 함수형 컴포넌트를 만들 때 화살표 함수 문법을 사용하겠다. 어떤 방식을 선택할지는 단지 각자의 취향에 달려 있다.


< Reactjs Code Snippet을 사용하여 코드 생성하기 >

* VS Code에서 React Code Snippet 확장 프로그램을 설치했다면 컴포넌트 코드를 간편하고 빠르게 생성할 수 있다. 에디터에서 rsc를 입력하고 [Enter]를 눌러 보자.

import React from 'react';

const MyComponent = () => {
    return (
        <div>
            
        </div>
    );
};

export default MyComponent;

* 코드를 생성하고 나면 컴포넌트 이름이 선택된 상태로 나타나는데, 여기서 수정하면 컴포넌트 이름을 변경할 수 있고 [Tab]을 누르면 선택을 해제할 수 있다.

* 참고로 클래스형 컴포넌트는 rcc를 입력하여 사용할 수 있다.

import React, { Component } from 'react';

class MyComponent extends Component {
    render() {
        return (
            <div>
                
            </div>
        );
    }
}

export default MyComponent;

(3) 모듈 내보내기 및 불러오기

[1] 모듈 내보내기(export)

* 방금 작성한 컴포넌트에서 맨 아래 코드를 확인해 보자.

export default MyComponent;

* 이 코드는 다른 파일에서 이 파일을 import 할 때, 위에서 선언한 MyComponent 클래스를 불러오도록 설정한다.

[2] 모듈 불러오기(import)

* 이번에는 App 컴포넌트에서 MyComponent 컴포넌트를 불러와서 사용해 보자. 기존에 App 컴포넌트에 있던 코드를 모두 지우고 다음과 같이 새로 작성해 보자.

import React from 'react';
import MyComponent from './MyComponent';

const App = () => {
  return <MyComponent />;
};

export default App;

* 위 코드에서 import 구문을 사용하는 두 번째 줄은 우리가 만든 MyComponent 컴포넌트를 불러온다. 코드를 저장하고 브라우저에서 다음과 같이 렌더링되었는지 확인해 보자.

'React_리액트 시작' 카테고리의 다른 글

(10) 컴포넌트 3  (0) 2023.11.29
(9) 컴포넌트 2  (0) 2023.11.29
(7) JSX 4  (0) 2023.11.29
(6) JSX 3  (1) 2023.11.29
(5) JSX 2  (0) 2023.11.29