React 의 Components 와 Props

‍박태우·2024년 9월 24일

React Study

목록 보기
2/4

Components 의 개념

  • 리액트는 여러개의 컴포넌트로 이루어져 있다. (컴포넌트로 페이지 구성)
  • 또한 하나의 컴포넌트는 여러개의 컴포넌트 조합으로 이루어 질 수 있다.

- 개념적으로는 자바 스크립트의 함수와 같이 동작한다.

(입력에 대한 정해진 출력을 내놓는다는 측면에서 비슷하다고 할 수 있다.)

(다른점이 있다면 입력이 Props 가 된다는 것이다. 출력은 React element가 된다.)

  • 컴포넌트와 엘리멘트의 관계를 그림으로 보면 아래와 같다.

Props의 정의

  • Props란? (Property 라는 말을 줄여씀, 속성이라는 의미)
    => React Component 의 속성을 의미한다.
    (위 붕어 빵 그림에서의 들어가는 재료 느낌)

=> 눈에 보이는 글자나 색깔등의 속성을 바꾸고 싶을 때 사용함

=> 실제 페이지 에서의 예시이다.

Props의 특징 및 사용법

1. 특징

1) read-only (읽기 전용)
=> ? 그럼 다른 Props 값으로 엘리먼트를 생성하려면 ?

answer) 새로운 값을 컴포넌트에 전달하여 새로 엘리먼트를 생성하면 된다.
(이 과정에서 엘리먼트가 다시 렌더링 되는 것이다.)

2. Pure 함수

3. Inpure 함수

=> React 컴포넌트의 정의와 관련이 있다. (Pure, Inpure)

모든 리액트 컴포넌트는 그들의 Props 에 관해서는 Pure 함수 같은 역할을 해야 한다. (즉 입력 값 Props는 리액트 컴포넌트에 의해 변하지 말아야 한다.)
같은 Props 에 대해서는 항상 같은 결과를 보여줘야 한다.

4. Props 사용법

App 컴포넌트 안에 Profile 컴포넌트가 존재하며 name introduction viewCount 의 3가지 속성을 넣어 줬다.


중괄호 값을 사용한 경우 : {} 안에 자바스크립트 코드가 들어감 (문자열, 정수, 변수, 다른 컴포넌트 등)

=> 이후에 위 속성(Props)들은 위 처럼 자바스크립트 객체가 된다.

=> 위 경우는 {} 안에 컴포넌트가 들어간 경우이다.

5. JSX 가 아닌 createElement 를 사용한 경우

=> 위의 props 안에 JS 객체를 넣으면 그게 곧 해당 컴포넌트의 props 가 된다.

=> 앞선 코드를 JSX를 사용하지 않게 되면 위와 같이 된다.
type : 컴포넌트의 이름
props : Javascript 객체가 들어가게 된다.
childeren : 하위 컴포넌트가 없기 때문에 children 에는 null 이 들어감


Component 만들기 및 렌더링

1. 컴포넌트의 종류

컴포넌트는 위처럼 함수 컴포넌트와 클래스 컴포넌트로 나뉜다.
리액트 초기버전에서는 클래스 컴포넌트만 존재 하였으나
클래스 컴포넌트가 사용하기 불편하다는 의견으로 인해 이후
함수 컴포넌트를 개선해서 주로 사용하게 되었다.
=> 함수 컴포넌트가 개발되면서 Hook 이라는 것이 개발됨

2. 함수 컴포넌트

간단한 코드를 가진다는 장점

3. 클래스 컴포넌트

자바 스크립트의 ES6의 Class 를 통해 만들어진 형태의 컴포넌트
함수 형의 컴포넌트와 달리 React.Component를 상속받아서 만듬
(모든 리액트의 클래스 컴포넌트가 이렇게 이루어진다.)
결과적으로 react 컴포넌트가 된다.

4. 컴포넌트의 이름

  • 항상 대문자로 시작해야 한다. (소문자의 경우 컴포넌트를 DOM 태그로 인식 하기 때문이다.)

첫번째 코드 : DOM 태그를 이용하여 엘리먼트를 만듬
두번째 코드 : 사용자가 정의한 Welcom 이라는 컴포넌트를 사용
(만약 소문자라면 리액트는 DOM 태그 라고 인식 하게 된다.)

5. 컴포넌트 렌더링

위 두 코드 모두 React 엘리먼트를 만들어내게 되는데, 이 엘리먼트를 렌더링 해서 DOM Element로 만드는 것이다.

  • 렌더링 코드

위에서 Welcome 이라는 함수 컴포넌트를 생성하고 있다. 해당 컴포넌트를 파라미터화 해서 ReactDOM.render() 함수를 호출한다.
=> 이렇게 되면 위와 같은 속성을 넣고 결과로 리액트 엘리먼트가 생성된다. 그리고 최종적으로 리액트 돔을 통해 실제 돔에 효과적으로 업데이트 된다.

Component 합성과 추출

1. 컴포넌트 합성

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

위 코드에서 Welcome 컴포넌트를 App 컴포넌트 내부에서 사용하는데 이때 props 를 달리하여 사용하는 것을 볼 수 있다. (컴포넌트 함성)

2. 컴포넌트 추출

  • 개념 : 복잡한 컴포넌트에서 여러개의 컴포넌트로 나누는 경우 (재사용 성 up)

댓글을 표시하기위한 Comment 컴포넌트

위 컴포넌트의 props 는 위와 같을 것이다.

  • 컴포넌트 추출하기

1) Avatar 추출하기

=> 위 부분의 아바타 부분을 별도의 컴포넌트로 만들어 보자!!!!

props 에 보편적인 단어인 user 로 선언하였는데 이는 재사용성 측면을 고려한 것이다.

  • 실제로 Comment 컴포넌트에 반영하기

위 처럼 적용이 가능하다. (가독성 증가)

2) UserInfo 추출하기

위 부분을 별도의 컴포넌트로 만들 것이다.

위처럼 사용자 정보 부분을 UserInfo 라는 컴포넌트로 추출함
컴포넌트 내부에 Avatar 라는 컴포넌트가 존재하는 것을 확인 가능

그리고 위처럼 Comment 컴포넌트에 UserInfo 컴포넌트를 반영함

=> 컴포넌트를 어느정도 까지 추출하는 것이 정해진 것은 없다.
다만 기능 별로 구분하는 것이 좋다.

댓글 컴포넌트 만들기

1) 컴포넌트 기본적으로 사용하기

  • Comment.jsx
import React from "react";

const styles = {
    wrapper:{
        margin : 8,
        padding : 8,
        display : "flex",
        flexDirection : "row",
        border: "1px solid grey",
        borderRadius : 16,
    },
    imageContainer : {},
image : {
    width : 50,
    height : 50,
    borderRadius : 25,
}, 
contentContainer : {
    marginLeft : 8,
    display: "flex",
    flexDirection : "column",
    justifyContent : "center",
},
nameText : {
    clolr : "black", 
    fontSize : 16,
    fontWeight : "bold",
},
commentText:{
    color : "black",
    fontSize : 16
}


}

function Comment(props){
    return(
        <div style={styles.wrapper}>
            <div style={styles.imageContainer}>
                <img src="https://upload.wikimedia.org/wikipedia/commons/8/89/Portrait_Placeholder.png"
                style={styles.image}/>
            </div>
            <div style={styles.contentContainer}>
                <span style={styles.nameText}>{props.name}</span>
                <span style={styles.commentText}>
                {props.comment}
                </span>

            </div>
        </div>
    );
}

export default Comment;

스타일 지정 및 기본적인 틀을 제공한다. 이때 props를 이용하여 name, comment 를 위와 같이 사용하였다.

  • CommentList.jsx
import React from "react";
import Comment from "./Comment";

function CommentList(props){
    return(
        <div>
            <Comment name={"박태우"} comment={"안녕하세요, 태우입니다."}></Comment>
            <Comment name={"나다"} comment={"안녕하세요, 나다입니다."}></Comment>
        </div>
    );

}
export default CommentList;

CommentList 컴포넌트에 Comment 컴포넌트를 사용하고 인자로 name 과 comment 를 줌으로서 아래의 index.js 에서 사용하고 그 결과를 얻음

  • index.js
const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
  <React.StrictMode>
    <CommentList></CommentList>
  </React.StrictMode>
)

결과 :


2) Comment 데이터를 별도의 객체로 분리하기

  • CommentList.jsx
import React from "react";
import Comment from "./Comment";

const comments = [
    {
        name : "박태우",
        comment : "안녕하세요 태우입니다.",
    },
    {
        name : "박태우123",
        comment : "안녕하세요 태우123입니다.",
    },
    {
        name : "박태우345",
        comment : "안녕하세요 태우345입니다.",
    },
]

function CommentList(props){
    return(
        <div>
            {comments.map((comments)=>{
                return <Comment name={comments.name} comment={comments.comment}></Comment>
            })
            }
            

        </div>
    );

}
export default CommentList;

이전과 달리 객체를 생성하여 객체의 모든 내용을 출력하도록 하였다.
(나머지 코드는 동일)

컴포넌트 분리 부분 다시 한번 확인하기 (조금 햇갈린다.)

profile
잘 부탁드립니다.

0개의 댓글