[ React.04.Component ]

carrotsman·2023년 2월 6일
0

프론트엔드

목록 보기
22/34
post-thumbnail

React Component

React의 컴포넌트는 앱을 구성하는 화면을 별개의 모듈로 나눈 단위로 Javascript와 JSX로 구성된 모듈을 반환하여 화면을 구축한다.

React 앱을 구현하는데 있어 가장 기본적인 단위, 컴포넌트다. 컴포넌트의 핵심은 기능의 모듈화와 재사용성에 있다. 기능을 모듈화하여 관리포인트를 통일화하여 유지보수성을 증대시킬 수 있고, 모듈 형태이기 때문에 필요한 곳에 레고처럼 끼워넣어 사용할 수 있다. 이것이 React 앱을 구현하는 가장 기본적인 방법이다.

CRA를 통해 React app을 만들면 App.jsx가 있다. App.jsx도 App이라는 컴포넌트를 return하는 형태로 되어있다. App은 모든 Component의 부모 컴포넌트다.


Component의 선언방식

Class형 Component

import React, { Component } from "react";

class Banner extends Component {
  render() {
    return <div>{this.props.name}</div>;
  }
}

export default Banner;
  • ES6 class를 활용한 Component 선언방식
  • state 기능 및 lifeCycle 메소드 지원
  • 최종적으로 render함수를 호출하는 형태
  • Component간 상호작용 가능
  • 비교적 React 초창기 Component 형태

함수형 Component

import React from "react";

const Banner = (props) => {
  return <div>{props.name}</div>;
}

export default Banner;
  • 함수형태 Component 선언방식
  • state 기능 및 lifeCycle 메소드 지원 X (hooks 추가)
  • Component간 상호작용 불가능
  • React에서 권장하는 Component 형태

💥 주의 : 컴포넌트의 이름은 항상 대문자로 시작한다.
React는 소문자로 시작하는 컴포넌트를 DOM 태그로 처리한다. 한마디로 소문자로 선언해서 사용하면 HTML 태그로 인식해 의도한대로 동작하지 않는다는 얘기다.


Class형 VS 함수형 Component

React에서는 위 2가지 선언방식을 지원했으나, 현재 공식문서에서는 함수형 Component와 hook을 결합한 형태를 권장한다. 권장하는 이유는 다음과 같다.

  • 편한 선언방식, 불필요한 코드를 줄이고 테스트 용이
  • 지속적인 성능 최적화 및 낮은 메모리 사용량
  • hook 제공으로 Class형 Component 컴포넌트 포용 가능
  • 함수의 모든 기능 이용 가능
  • props에 따른 랜더링 결과 보장

👽 React Hook??

React16.8 부터 Hook이란 개념이 도입되었다. Hook을 이용해 함수형 컴포넌트도 state관리와(useState) 라이프사이클API(useEffect)를 심플하게 사용할 수 있게 됐다. 그 덕분에 가독성이 떨어지는 클래스형 함수를 굳이 사용할 필요가 없게 됐다.

React hook에 대해서는 차후 포스팅에서 자세히 다루겠다.


Class형 Component의 치명적 결함

함수형 컴포넌트의 사용을 권장하는 이유 중 props에 따른 랜더링 결과 보장 내용에 대해 설명한다. 이것은 React의 Flux패턴을 도입한 것과 유사한 이유다. 가령 다음과 같은 컴포넌트가 있다고 가정해보자.

class ProfilePage extends React.Component {
	showMessage = () => {
		alert(`${this.props.user}를 팔로우 했습니다`);
	}

	handleClick = () => {
		setTimeout(this.showMessage, 5000);
	}

	render() {
		return <button onClick={this.handleClick}>Follow</button>;
	}
}

사용자 A와 B가 있다고 가정해보자. A를 팔로우하고 5초 이내로 B의 프로필을 클릭했을 때 'B를 팔로우 했습니다' 라는 메세지를 얻게된다. 이유는 this는 mutable(변경가능)하기 때문이다. A를 클릭후 B 프로필로 이동하는 경우, A에 대한 요청이 진행되고 있는 상황에서 클래스 컴포넌트가 다시 렌더링된다. 하지만 함수의 진행에 있어 이전 A를 바라봐야 하지만 결과는 B로 할당하게 된다. showMessage 함수가 새로운 this.props의 user를 읽는 것이다. 이러한 현상 때문에 예기치 못한 결과(결국 production에서는 버그임)가 발생할 수 있다.

const ProfilePage = (props) => {
	showMessage = () => {
		alert(`${props.user}를 팔로우 했습니다`);
	}

	handleClick = () => {
		setTimeout(showMessage, 5000);
	}
	return (
		<button onClick={handleClick}>Follow</button>
	)
}

반면 함수형 컴포넌트의 경우 props는 immutable(불변)의 특성을 띄고 있기 때문에, 다시 랜더링되더라도 요청했던 시점의 user를 바라본다.

👍 결론적으로 함수형 Component를 사용하는 것이 바람직하다.


Component 사용

이제 Component를 선언하고 App.jsx에 활용해보자. LoginComponent를 만들고 App에서 활용한다 가정했을때 다음처럼 사용하면 된다.

  • LoginComponent.jsx
/* 이것들이 react에서 제공하는 hook이다. 추후 하나씩 다룬다. */
import React, { useState, useEffect, Suspense, useRef } from 'react';

/**
 * 로그인 Component
 */
const LoginComponent = (props) => {
	return <div>로그인페이지</div>;
};

export default LoginComponent;
  • App.jsx
import React, { Suspense } from 'react';
import LoginComponent from './component/Layout';

const App = (props) => (
	<Suspense>
		<LoginComponent {...props} />
	</Suspense>
);

export default App;

다음 코드처럼 Component를 선언하고 해당 기능을 App.jsx에서 import하여 사용한다. react의 모든 화면은 다음과 같은 구조로 작성된다.


목적에 따른 Component

목적에 따라 프리젠테이션(presentational) 컴포넌트와 컨테이너(container) 컴포넌트로 분류할 수 있다.

Presentational Component

  • View 담당 컴포넌트 (UI 작성)
  • 내부에 프레젠테이셔널 컴포넌트와 컨테이너 컴포넌트 포함 구조
  • state 접근을 최소화, props로 데이터, 함수 활용
  • state또한 UI에 대한 state만 활용하는 것을 권장

Container Component

  • 다른 프레젠테이션 컴포넌트나 컨테이너 컴포넌트를 관리
  • 내부에 DOM 엘레멘트를 (UI) 작성하지 않는다 (사용하는 경우 감싸는 용도)
  • 스타일을 가지고 있지 않는다.
  • state를 가지고 있고 redux를 통해 데이터 패치
  • dispatch 함수 구현체

정리하며

오늘은 React를 구성하는 가장 작은 단위, 컴포넌트에 대해 알아봤다. React 개발에 있어 가장 기초적인 부분인 만큼 개념 확립이 필수적이다. 다음 포스팅에선 React의 통곡의 벽, state, props에 대해 풀어보겠다.

오늘 저녁은 소갈비찜이다. 🥕


참고 : https://ko.reactjs.org/docs/components-and-props.html
https://onlyfor-me-blog.tistory.com/460
https://ko.reactjs.org/docs/react-component.html#render
https://born-dev.tistory.com/27

profile
당근먹고 강력한 개발

0개의 댓글