오늘은 프론트 엔드 분야에서 가장 핫한 라이브러리인 리액트에 대해서 정리하겠습니다.
프론트 엔드 분야의 역사를 크게 세 부분으로 나누어보자면 다음과 같습니다.
웹 페이지가 사용자와의 상호작용이 많아지고 복잡해지면서 새로운 기술들이 발전해 왔습니다. 그리고 현재는 라이브러리와 프레임워크를 사용하는 3세대라 할 수 있습니다.
3세대의 대표적인 기술로는 Angular, React, Vue가 있지만 그 중에서도 리액트가 가장 많이 사용되고 있습니다. 리액트는 페이스북에서 제작한 자바스크립트 기반 라이브러리 입니다.
Angular, vue는 프레임워크이므로 일정한 규격 내에서 정해진 규칙에 따라 개발을 해야하는 반면, 리액트는 라이브러리로 좀 더 자유롭게 개발을 진행할 수 있습니다. 자유도가 높은만큼 필요한 라이브러리(Router, Redux 등)를 추가로 설치해야 합니다.
React는 상호작용이 많은 UI를 만들 때 생기는 어려움을 줄여줍니다. 어플리케이션 상태에 대한 간단한 뷰를 설계하고 데이터가 변경됨에 따라 적절한 컴포넌트만 효율적으로 갱신하고 렌더링합니다.
컴포넌트 로직은 템플릿이 아닌 JavaScript로 작성됩니다. 따라서 다양한 형식의 데이터를 앱 안에서 손쉽게 전달할 수 있고, DOM과는 별개로 상태를 관리할 수 있습니다.
컴포넌트 기반으로 개발을 하게 되면 컴포넌트는 서로 독립적으로 사용되기 때문에 코드 재활용이 용이하며, 디버깅하기도 쉽습니다.
리액트는 JSX라는 문법을 사용합니다. 이 문법은 JavaScript가 확장된 문법으로 브라우저가 이해할 수 없습니다. 브라우저가 이해할 수 있도록 JavaScript와 HTML로 변환해 주는 과정이 필요합니다. 그 때, 우리는 "Babel"이라는 자바스크립트 컴파일러를 통해 JSX문법으로 작성한 코드를 브라우저에 렌더링 할 수 있게습니다.
리액트에서는 DOM과는 다르게 CSS,JSX 문법만을 가지고 웹 개발이 가능합니다. 우선 아래의 코드는 JSX 문법을 사용하지 않고 렌더링하는 코드입니다.
// React.createElement(component, props, ...children)
const component = React.createElement(h1, 'hi', "hello world")
// 'hi'라는 props가지고 hello world라는 텍스트를 가진 h1태그인 컴포넌트를 변수에 할당
import React from "react";
export default function App() {
const user = {
firstName: "React",
lastName: "JSX Activity"
};
function formatName(user) {
return user.firstName + " " + user.lastName;
}
// JSX 없이 활용한 React
return React.createElement("h1", null, `Hello, ${formatName(user)}!`);
// Hello, React JSX Activity!
}
아래의 JSX 문법을 사용한 예시입니다. App 이라는 함수 컴포넌트는 HTML 테그 덩어리를 리턴하고 리턴된 요소가 화면에 렌더링 됩니다.
이렇게 JSX문법을 사용하면 렌더링하고자하는 요소를 명시적으로 나타낼 수 있습니다.
import React from "react";
export default function App() {
const user = {
firstName: "React",
lastName: "JSX Activity"
};
function formatName(user) {
return user.firstName + " " + user.lastName;
}
return <h1>Hello, {formatName(user)}!</h1>;
// Hello, React JSX Activity!
}
위에서 리엑트를 사용하는 HTML요소들을 렌더링하는 기본적인 방법을 정리했습니다. 리엑트를 사용하면 편리하게 명시적인 코드를 작성할 수 있습니다. 하지만 'Babel' 컴파일러를 통한 JSX 컴파일링, 유닛테스트, 파일 번들링 등 프로젝트에 사용되는 여러가지 패키지를 설치하고 설정하는데 많은 어려움이 있습니다.
하지만 CRA를 통해 매우 간편하게 미리 설정된 개발환경을 경험할 수 있습니다. 우선 터미널에서 프로젝트를 시작할 경로로 이동 후 다음과 같은 명령어를 사용합니다.
npx create-react-app "프로젝트명"
설치가 완료되고 폴더를 열어보면 다음과 같이 개발에 필요한 패키지와 소스들이 잘 설치되어 있는 것을 확인할 수 있습니다.
설치된 파일을 살펴 보면 리액트가 어떻게 브라우저에 렌더링을 해주는지 조금이나마 이해할 수 있습니다. public이라는 폴더에 존재하는 index.html에서 id가 root인 요소를 통해 App이라는 컴포넌트를 렌더링한다는 의미입니다. 이렇게 각각의 컴포넌트가 import되어 index.html
이라는 하나의 파일에서 렌더링이 가능하게 되고, 이로 인해 SPA(Single Page Apllication) 개발이 가능하게 됩니다.
컴포넌트를 생성하는 방법에는 두 가지가 있습니다. 하나는 함수를 이용한 방법이고 하나는 클래스를 이용한 방법입니다. 다음은 같은 기능을 하는 두 가지 컴포넌트 입니다. 컴포넌트를 생성할 때 주의해야하는 점은 반드시 첫글자를 대문자로 사용해야 합니다. 이제 새로운 컴포넌트를 생성해 보겠습니다.
App.js 파일에서 'Hello'라는 children을 가지는 div 요소를 리턴하는 Hello라는 함수 컴포넌트를 생성합니다. 그 이후 export 해주면 브라우저에 Hello라는 글자가 렌더링되게 됩니다. 이것이 가능한 이유는 위에서 설명했지만 export된 App 컴포넌트를 index.html에서 렌더링 해주기 때문입니다.
// App.js
import React from "react";
function Hello() {
return <div>Hello</div>;
}
export default function App() {
return <Hello />;
}
Hello라는 클래스 컴포넌트는 함수 컴포넌트와는 다르게 React.Componenet를 상속 받아 render()라는 메서드를 사용하여 렌더링 합니다.
// App.js
import React from "react";
class Hello extends React.Component {
render() {
return <div>Hello</div>;
}
}
export default function App() {
return <Hello />;
}
캄포넌트에는 생명주기가 존재합니다. 컴포넌트 생명주기(lifecycle)란 컴포넌트가 페이지에 렌더링 되기 위해 준비하는 과정에서부터 제거될 때까지의 기간을 말하며, 클래스형 컴포넌트는 이러한 생명주기 중 특정 시점에 대하여 원하는 구문을 실행할 수 있도록 생명주기 메소드를 지원합니다.
그렇기에 과거에는 클래스형 컴포넌트를 이용한 개발이 많이 이루어 졌지만 함수형 컴포넌트에서도 생명주기를 제어할 수 있는 Hooks이라는 기술이 생긴 이후에는 클래스 컴포넌트 보다는 함수형 컴포넌트를 주로 사용하는 추세입니다.
reference : https://ko.reactjs.org/
오 함수 컴포넌트, 클래스 컴포넌트 차이점도 배워가네요! 깔끔한 정리 굿입니다~~