본문 바로가기

Front-end/React

[React] 컴포넌트(Component)

 

1. 컴포넌트(Component)

- 개념적으로 자바스크립트 함수와 비슷함, 입력을 받고 정해진 출력을 내뱉음

- Props를 입력받고 리액트 엘리먼트가 출력됨 => 어떠한 속성들을 입력받아 그에 맞는 리액트 엘리먼트를 생성하여 리턴해주는 것

 

1) 컴포넌트의 종류

- 클래스 컴포넌트: 리액트 초기 버전에서 주로 사용

- 함수 컴포넌트: 클래스 컴포넌트가 사용하기 불편하여 함수 컴포넌트를 개선하여 주로 사용하게 됨

(cf. 함수 컴포넌트를 개선하는 과정에서 개발된 것이 훅Hook)

 

2) 컴포넌트 만들기 좋은 것들

- 반복적인 html 축약할 때

- 큰 페이지들

- 자주 변경되는 것들

 

 

3) 컴포넌트의 단점

다른 function에 정의된 state를 가져다 쓸 때 문제 생김(정의되지 않았으니까)

 

 

 

2. 컴포넌트 만들기

 

1) 함수 컴포넌트

// 함수 컴포넌트
import React from "react";

function Welcom(props) { // props 객체를 받음
	return <h1>안녕, {props.name}</h1> // 인사말이 담긴 리액트 엘리먼트를 리턴
}

export default Welcom;



// 컴포넌트 만드는 다른 문법 
const Welcom = () => {
	return(
    	<h1>안녕</h1>
    )
}

- 간단한 코드가 장점

함수 컴포넌트 만들기 
1) function 만들기
2) return() 안에 html 넣기
3) <함수명></함수명>  또는 <함수명/> 을 써서 사용하기

 

 

2) 클래스 컴포넌트

- 자바스크립트 ES6의 클래스라는 것을 사용해서 만들어진 형태의 컴포넌트

- 함수 컴포넌트에 비해서 몇 가지 추가적인 기능을 갖고 있음

- 리액트의 모든 클래스 컴포넌트는 React.Component를 상속받아서 만들고, React.Component를 상속받았기 때문에 결과적으로 리액트 컴포넌트가 됨

- state사용 시 기존 state 전체를 변경하는 것이 아닌 변경사항만 반영

// 클래스 컴포넌트
import React, {Component} from "react";


class Welcom extends React.Component{
	constructor(props) {
    	super(props);
        this.state = {
            name : 'kim',
            age : 20
        }
    }
    
	render() {
    	return (
            <div>
            	<h1>안녕{this.state.name}</h1>
            	<button onClick={() => {
                	this.setState({age : 21})
                }}>버튼</button>
            </div>
    }
}

export default Welcom;

 

 

3) 컴포넌트 이름 짓기

- 컴포넌트의 이름은 항상 대문자로 시작해야 함(리액트는 소문자로 시작하는 컴포넌트를 DOM 태그로 인식함)

// HTML div 태그로 인식
const element = <div />;

// Welcom이라는 리액트 컴포넌트로 인식
const element = <Welcom name="sky" />;

 

4) 컴포넌트 렌더링

컴포넌트는 붕어빵 틀의 역할을 하기 때문에 화면에 보이는 것은 엘리먼트라는 붕어빵

 

- 컴포넌트로부터 엘리먼트 만들기

// DOM 태그를 사용한 element
const element = <div />;

// 사용자가 정의한 컴포넌트를 사용한 element
const element = <Welcom name="sky" />;

 

- 위 엘리먼트를 렌더링 하기

// Welcom이라는 함수 컴포넌트 선언
function Welcom(props) {
	return <h1>안녕, {props.name}</h1>; 
}

const element = <Welcom name="sky" />; // <Welcom name="sky" /> 라는 값을 가진 element 파라미터로 ReactDOM.render() 호출
ReactDOM.render(
	element, // Welcom 컴포넌트에 {name: "sky"} 라는 props를 넣어서 호출, 그 결과 리액트 엘리먼트 생성
    document.getElementById('root')
);

 

 

4. 컴포넌트 합성(Composing component)

- 여러 개의 컴포넌트를 합쳐서 하나의 컴포넌트를 만드는 것

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

// props의 값을 다르게 해서 Welcom 컴포넌트를 여러 번 사용
function App(props) { 
	return (
        <div>
        <Welcome name="Mike" />
        <Welcome name="Steve" />
        <Welcome name="Jane" />
        </div>
    )
}

ReactDOM.render(
	<App />, 
    document.getElementById('root')
);

 

 

5. 컴포넌트 추출(Extracting components)

- 큰 컴포넌트에서 일부를 추출해서 새로운 컴포넌트를 만드는 것

- 재사용성 상승: 컴포넌트가 작아질수록 해당 컴포넌트의 기능과 목적이 명확해지고 props도 단순해짐

- 재사용성 상승으로 인한 개발 속도 향상

 

// Comment 컴포넌트
// 댓글을 표시하기 위한 컴포넌트로 내부에 작성자의 프로필 이미지와 이름, 댓글 내용, 작성일을 포함함
function Comment(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>
    );
}

 

추출하기

// Avatar 컴포넌트 추출
// (author을 user로 수정)
function Avatar(props) {
    return (
        <img className="avatar"
            src={props.user.avatarUrl}
            alt={props.user.name}
        />
    );
}

 

// 사용자 정보를 담고 있는 UserInfo 컴포넌트 추출
function Userlnfo(props) {
     return (
        <div classNafne="user-info">
            <Avatar user={props.user} /> 
            <div className="user-info-name">
                {props.user.name}
            </div>
        </div>
    );
}

 

추출이 반영된 comment

function Comment(props) {
    return (
        <div className="comment">
            <User-Info user={props.author} />  

            <div className="comment-text">
                {props.text}
            </div>

            <div className="comment-date">
                {formatDate(props.date)}
            </div>
        </div>
    );
}

Comment 컴포넌트가 UserInfo 컴포넌트를 포함하고 있고, UserInfo컴포넌트가 Avatar 컴포넌트를 포함하고 있는 구조

- Comment의 글과 작성일이 나오는 부분도 별도의 컴포넌트로 추출이 가능

-> 컴포넌트를 어느 정도 수준까지 추출하는 것이 좋은지에 대해 정해진 기준은 없음

-> 하지만 기능 단위로 구분하는것이 좋으며, 곧바로 재사용이 가능한 형태로 추출하는 것을 권장

 

 

 

 

'Front-end > React' 카테고리의 다른 글

[React] 훅(Hook)  (0) 2023.05.11
[React] State와 생명주기(LifeCycle)  (0) 2023.05.10
[React] 리액트 엘리먼트(element) 렌더링  (0) 2023.05.07
[React] JSX(JavaScript and XML)  (0) 2023.05.07
[React] 리액트 시작하기  (0) 2023.05.07