본문 바로가기
[FrontEnd]/React

React - Components & Props

by 황원용 2023. 6. 2.
728x90

Components

  • 리액트는 컴포넌트 기반의 구조이다.
  • 리액트는 모든 페이지가 컴포넌트로 구성되어 있다.
  • 하나의 컴포넌트 다른 여러 컴포넌트의 조합으로 구성될 수 있다.
  • 마치 레고 블록을 조립하듯이 컴포넌트를 모아서 새로운 컴포넌트를 개발한다.
  • 하나의 컴포넌트를 반복적으로 사용함으로써 전체 코드의 양을 줄일 수 있다.
  • 이를 통해 자연스럽게 개발 시간과 유지보수 비용을 줄일 수 있다.
  • 자바스크립트의 함수와 비슷하다. 입력을 받아 정해진 출력을 내보내기 때문이다.
  • 그러나, React component에서 입력은 Props이며, 출력은 React element라는 차이점이 있다.
  • React component의 역할은 어떤 속성을 입력받아 그에 맞는 React element를 리턴하는 것이다.
  • 컴포넌트의 이름은 항상 대문자로 시작해야 한다. 리액트는 소문자로 시작하는 컴포넌트를 DOM 태그로 인식하기 때문이다.

 

 

Props

  • Property를 줄인 말이다.
  • 리액트에서는 속성이란 뜻으로 사용된다.
  • 컴포넌트에 전달할 다양한 정보를 담고 있는 자바스크립트 객체이다.
  • Component가 Element를 만드는 틀이라고 한다면 Props는 각 Element 안의 들어가는 재료(속성)이라고 할 수 있다.

 

Props의 특징

  • 읽기 전용(Read-Only)이다.(불변)
  • 모든 리액트 컴포넌트는 Props를 직접 바꿀 수 없고, 같은 Props에 대해서는 항상 같은 결과를 보여줘야 한다.

 

Props의 사용법

function App(props) {
	return (
    	<Profile
    		name="황인팁"
            introduction="안녕하세요, 황인팁입니다."
            viewCount={1500}
        />
    )
}
  • JSX를 사용하는 경우 key value 쌍의 형태로 컴포넌트에 props를 넣을 수 있다.
  • 위 코드는 App 컴포넌트 안에 Profile 컴포넌트가 있다.

 

{
	name: "황인팁",
    introduction: "안녕하세요, 황인팁입니다."
    viewCount: 1500
}
  • props는 위와 같은 형태의 자바스크립트 객체가 된다.

 

function App(props) {
	return (
    	<Layout
    		width={2560}
            height={1440}
            header={
            	<Header title="황인팁의 블로그입니다." /> // 컴포넌트 넣기
            }
            footer={
            	<Footer />
            }
        />
    );
}
  • 위와 같이 props 중괄호를 사용해서 props의 값으로 컴포넌트도 넣을 수 있다.
  • JSX를 사용하는 경우 컴포넌트에 props를 넣을 수 있다. 

 

JSX를 사용하지 않고 컴포넌트에 props를 넣는 경우

React.createElement{
	Profile,
    {
        name= "황인팁",
        introduction: "안녕하세요, 황인팁입니다."
        viewCount: 1500
    },
    null // 하위 컴포넌트가 없기 때문에 children에는 null
};
  • 이는 JSX를 사용하지 않을 때 예시를 보여준 것이지 실제로 이런 식으로 개발하지 않는다.

 

 

Component의 종류

Function Component(함수 컴포넌트)

  • 리액트의 컴포넌트를 함수로 생각하면 이해하기 쉽다.
  • 클래스 컴포넌트에 비해 간결한 코드 구성을 가지고 있다.

Class Component(클래스 컴포넌트)

  • 자바스크립트 ES6의 클래스를 이용하여 만들어진 컴포넌트이다.
  • 처음에는 함수 컴포넌트보다 우위에 있었지만 사용하기 불편하여 지금은 거의 사용되지 않는다.

 

 

Component 렌더링

  • Component가 실제로 화면에 렌더링 되지 않고 Component로부터 나온 Element가 실제 화면으로 보여진다. 
  • 따라서 렌더링을 위해서는 Component로부터 Element를 만들어야 한다.

 

function Welcome(props) {
	return <h1>안녕, {props.name}</h1>;
}

const element = <Welcome name="황인팁" />;
ReactDom.render(
	element,
    document.getElementById('root')
);
  • 위 코드에서는 Welcome이라는 함수 컴포넌트를 선언하고 있다.
  • Welcome name="황인팁"이라는 이름을 가진 Element를 파라미터로 해서 ReactDOM.render() 함수를 호출한다.
  • 이렇게 하면 리액트는 Welcome 컴포넌트에 name="황인팁"이라는 props를 호출하고 그 결과로 React element가 생성된다.
  • 생성된 React element는 최종적으로 React DOM을 통해 실제 DOM에 업데이트되고 사용자가 브라우저를 통해 볼 수 있게 된다.

 

 

Component 합성

  • Component 안에 또 다른 Component를 사용할 수 있다.
  • 이를 이용해 복잡한 화면 구성을 여러 개의 Component를 활용해 만들 수 있다.

 

예시

function Welcome(props) {
	return <h1>Hello, {props.name}</h1>;
}

function App(props) {
	return (
    	<div>
        	<Welcome name="Mike" />
            <Welcome name="Steve" />
            <Welcome name="Jane" />
        </div>
    )
}

ReactDOM.render(
	<App />,
    document.getElementById('root')
);
  • 여기서 App은 Welcome Component 3 개를 포함하고 있는 Component가 된다. 
  • 이처럼 여러 개의 Component를 합쳐 또 다른 Component를 만드는 것을 Component 합성이라고 한다.
  • Welcome Components는 각기 다른 props를 가지고 있다.
  • 이는 리액트로만 구성된 웹의 기본적인 구성이다.
  • 만약 기존에 있던 웹에 리액트를 연동하는 방식이라면 root node가 하나가 아닐 수도 있기 때문에 이런 구조가 아닐 수도 있다.

 

 

Component 추출

  • Component 합성과는 반대로 복잡한 Component를 쪼개서 여러 개의 Component를 나눌 수도 있다. 
  • 이를 잘 활용하면 Component의 재사용성이 올라간다.
  • Component가 작아질수록 해당 Component의 기능과 목적이 명확해지고 props도 단순해져 다른 곳에서 사용 가능할 확률이 올라간다.

 

예시

function Commnet(props) {
	return (
    	<div className="comment">
        	<div className="user-info">
            	<img className="avatar"
                	src={props.author.avatarUrl}
                    alt={props.author.name}
                />
                <div className="user-info-name">
                	{props.author.name}
                </div>
            </div>
            
            <div className="comment-text">
            	{props.text}
            </div>
            
            <div className="comment-date">
            	{formatDate(props.date)}
            </div>
        </div>
    );
}

 

위 Component의 props

props = {
	author: {
    	name: "황인팁",
        avatarUrl: "https://...",
    },
    text: "댓글 내용",
    date: Date.now()
}
  • Comment Component에서는 img 태그를 사용하여 사용자의 프로필 이미지를 표시한다.
  • 이 부분을 추출해서 Avatar라는 별도의 Component를 만들어보자.

 

Avatar Component 추출하기

function Avatar(props) {
	return (
        <img className="avatar"
            src={props.author.avatarUrl}
            alt={props.author.name}
        />
	)
}
  • 다른 곳에서 사용할 수 있다는 가능성을 고려하여 author 대신 user로 변경한다.

 

function Avatar(props) {
	return (
        <img className="avatar"
            src={props.user.avatarUrl}
            alt={props.user.name}
        />
	)
}

 

추출한 Avatar Component를 Comment Component에 반영하기

function Commnet(props) {
	return (
    	<div className="comment">
        	<div className="user-info">
            	<Avatar user={props.author} /> // 변경 
                <div className="user-info-name">
                	{props.author.name}
                </div>
            </div>
            
            <div className="comment-text">
            	{props.text}
            </div>
            
            <div className="comment-date">
            	{formatDate(props.date)}
            </div>
        </div>
    );
}

 

UserInfo Comment 추출하기

function UserInfo(props) {
	return (
    	<div className="user-info">
            <Avatar user={props.author} /> 
            <div className="user-info-name">
                {props.author.name}
            </div>
        </div>
    );
}

 

추출한 UserInfo Comment Component 반영하기

function Commnet(props) {
	return (
    	<div className="comment">
            <UserInfo user={props.author} />
            <div className="comment-text">
            	{props.text}
            </div>
            
            <div className="comment-date">
            	{formatDate(props.date)}
            </div>
        </div>
    );
}
  • Component를 어디까지 추출할 것인가에 대해서 정해진 것은 없지만 기능 단위로 구분하는 것이 좋고, 나중에 곧바로 재사용 가능한 형태로 추출하는 것이 좋다.
  • 재사용이 가능한 Component를 많이 가지고 있을수록 개발 속도가 빨라진다.

 

 

 

참고

인프런 - 차음 만난 리액트

728x90

'[FrontEnd] > React' 카테고리의 다른 글

React - Hooks  (0) 2023.06.02
React - State & Lifecycle  (0) 2023.06.02
React - Rendering Elements  (0) 2023.06.01
React - JSX  (0) 2023.06.01
리액트(React) 기초와 관련 용어 정리  (0) 2023.06.01