[React.js] Component 기본
🤷 Component(컴포넌트)의 이해
React 프로젝트의 UI를 독립적이고 재사용이 가능하도록 나눈 최소 단위를 Component라고 한다. (반복적인 패턴구현 용이)
Javascript 함수와 유사하다. 'props'라는 입력을 받은 뒤, React element를 반환한다고 이해하자.
* 컴포넌트는 단순한 템플릿이 아님! - 주어진 데이터를 반영한 UI를 구성하며, Lifecycle API로 켤 때, 변할 때, 꺼질 때 각각 구현도 가능!
- UI / UX 개념과 차이점
- UI(User Interface): 사용자가 App을 사용할 때 마주하는 디자인, 레이아웃, 인터페이스 등 기술적인 부분을 얘기한다. 단순히, 보여지는 화면만을 얘기하는게 아니라, 폰트/칼라/줄간격 같은 세부요소 및 반응형/애니메이션 같은 영역까지 포괄적으로 의미한다.
- UX(User Experience): UI에서 파생된 개념으로, 사용자가 App을 사용하는 경험 혹은 경향을 의미한다. 제일 먼저 터치하는 화면, 선택하는 플로우 등을 분석해서, 더 효율적이고 편리하도록 개선되는 프로세스를 일컫는다. 통계 데이터 기반 분석이 보편적.
- React Library 가져오기
React 객체(라이브러리)의 메소드들을 .js파일에서 사용하기 위해, 가장 먼저 React 객체를 변수에 연결해줘야 한다.
import React from 'react';
//import ReactDOM from 'react-dom';
* 이전 .createElement() 메소드 사용을 위해, React 변수에 'react' 라이브러리에서 가져왔다.(import)
📒 Component 정의 방법: 함수형 vs 클래스형
컴포넌트를 정의하는 방법은 대표적인 '함수형'과, ES6에서 추가된 class를 활용한 '클래스'형이 있다.
- 클래스형 컴포넌트
- ES6 버전에서 지원하게 된 class 기반의 선언방법
- render() 메소드(함수)가 반드시 존재해야 한다.
- state 사용, Life Cycle API 사용이 가능하다.
import React from 'react';
import ReactDOM from 'react-dom';
// 선언방법: class 클래스명 extends React.Component{메소드 활용};
class MyComponentClass extends React.Component{
render() { //render() 함수형 메소드
return <h1>Hello world</h1>
};
};
ReactDOM.render(
<MyComponentClass />, // JSX에서 Component로 인식
document.getElementById('app')
);
* 클래스명은 첫글자가 대문자인 UpperCammelCase로 작성한다.
(JSX는 HTM태그와 컴포넌트 둘 다 인식가능. 소문자 = HTML / 대문자 = 컴포넌트)
- 함수형 컴포넌트
- 클래스형에 비해 선언하기 편하다.
- 메모리 용량을 비교적 적게 차지한다.
- 빌드 후 배포시 결과물의 크기가 작다.
function App() {
const test = "";
return <div>{test}</div>
}
클래스형과 함수형의 코딩예시 및 장단점에 대해 정리했다. 하지만, 크기나 성능에서 차이가 크지 않다.
또한, 함수형 컴포넌트에서 지원하지 않는 기능도 React Hooks로 가능해졌다.
결과적으론, 사용자의 선택에 따라 결정되는 부분이며, 공식 메뉴얼은 함수형 + Hooks를 권장하나 결국 기본환경인 클래스형 컴포넌트에 대해서도 알아두는게 좋다고 한다.
https://eodevelop.tistory.com/68 (출처: eodevelop님의 tistory 블로그)
📒 클래스형 Component 다양한 정의
- 외부 JS객체 요소를 활용한 렌더링
import React from 'react';
import ReactDOM from 'react-dom';
// Object for Reference
const owl = {
title: 'Excellent Owl',
src: 'https://content.codecademy.com/courses/React/react_photo-owl.jpg'
};
// Component class
class Owl extends React.Component {
render() {
return (
<div>
<h1>{owl.title}</h1>
<img
src={owl.src}
alt={owl.title}
/>
</div>
)
}
}
ReactDOM.render(<Owl />, document.getElementById('app'))
- 컴포넌트에 로직 적용
class Random extends React.Component {
render() {
// Logic before render
const n = Math.floor(Math.random() * 10 + 1);
// Return with logic
return <h1>The number is {n}!</h1>;
}
}
여기서, const n 로직이 반드시 컴포넌트 메소드(render() function) 안에 포함되어 있어야 한다.
- 컴포넌트에 조건문 적용
const fiftyFifty = Math.random() < 0.5;
class TonightsPlan extends React.Component{
render() {
// Write if statements firstly
let plan;
if (fiftyFifty) {
plan = `Tonight I'm going out WOOO`
}
else {
plan = `Tonight I'm going to bed WOOO`
}
// then return
return (
<h1>{plan}</h1>
)
}
};
조건문 역시 컴포넌트 메소드(render() function) 안에 포함되며, return 전에 선언한다.
- 컴포넌트 내의 this문 적용
import React from 'react';
import ReactDOM from 'react-dom';
class MyName extends React.Component {
get name() {
return 'whatever-your-name-is-goes-here'
}
render() {
return <h1>My name is {this.name}.</h1>;
}
}
ReactDOM.render(<MyName />, document.getElementById('app'));
* this는 메소드를 호출한 객체를 저장하는 속성이다. 여기선 class MyName을 지칭한다.
this는 조건에 따라 전역객체(window)도, 특정객체도 지칭한다. 참고출처로 학습했고, 추후 this 별도로 포스팅하겠다.
https://www.zerocho.com/category/JavaScript/post/5b0645cc7e3e36001bf676eb (출처: JS유튜버 zerocho님 블로그)
- 컴포넌트 내 Event Listener 적용
import React from 'react';
import ReactDOM from 'react-dom';
class Button extends React.Component {
scream() {
alert('whatever-your-name-is-goes-here')
}
render() {
return <button onClick={this.scream}></button>
}
}
ReactDOM.render(<Button />, document.getElementById('app'));
class 안에 scream(), render() 두 개의 메소드가 패키징됬고, this는 위처럼 class Button을 지칭한다고 이해함.
📒 함수형 Component (stateless)
// 일반적인 클래스형 컴포넌트
export class MyComponentClass extends React.Component {
render() {
return <h1>Hello world</h1>;
}
}
// stateless 함수형 컴포넌트
export const MyComponentClass = () => {
return <h1>Hello world</h1>;
}
// 둘 다 정상동작함
ReactDOM.render(
<MyComponentClass />,
document.getElementById('app')
);
이처럼, 두 가지 정의방법에서 모두 정상동작하며 함수형이 구문은 더 짧은 것을 알 수 있다.(render() 동작을 return으로 실행)
- 함수형 컴포넌트의 정보 전달: props를 통해 이루어진다.(stateless)
import React from 'react';
import ReactDOM from 'react-dom';
// 클래스형 컴포넌트
export class NewFriend extends React.Component {
render() {
return (
<div>
<img src={this.props.src} />
</div>
);
}
}
// 함수형 컴포넌트
export function NewFriend (props) { // props를 인자로 받아야 한다.
return (
<div>
<img src={props.src} /> // props.src를 src로 활용!(this 불필요)
</div>
);
}
ReactDOM.render(
<NewFriend src="https://content.codecademy.com/courses/React/react_photo-squid.jpg" />,
document.getElementById('app')
);
위는 NewFriend 컴포넌트를 클래스형, 함수형으로 작성한 것이다. 함수형의 인자로 props를 넣어주면 정보를 받을 수 있다.
함수형 컴포넌트는 간결함과 직시성의 이유와, Hooks을 통해 state를 적용할 수 있게 되면서 클래스형에 비해 자주 사용된다.
* Hooks: 클래스형 컴포넌트에서 사용되던 state를 함수형 컴포넌트에서도 사용할 수 있게 해주는 기능 (별도 포스팅)
React의 장점 중 하나인 효율성과 직관되는, UI의 기본단위인 Component에 대해 새롭게 알게 되었다.
공부를 하면서, UI/UX에 대한 정확한 개념이라던지, JS의 this의 성질 등 중간중간 짚어야 할 점이 많음을 느꼈다.
블로그에 노트를 병행하고, 거기다 중간중간 모호한 개념 공부까지.. 시간은 많이 걸리겠지만 그만큼 정확한 공부가 중요한 것 같다!
(11.27) 함수형 컴포넌트에 대해 추가했다. Hooks를 통해 state를 보완해서 사용 가능하다고 하는데, 공부와 포스팅을 통해 확인하겠다.