ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [ReactJS] Components and Props
    Programming/ReactJS 2022. 11. 30. 02:03

    Component

    리액트에서는 모든 페이지가 컴포넌트로 구성되어 있다. 작은 컴포넌트들이 모여 하나의 컴포넌트를 구성하고 그렇게 하나의 페이지가 완성된다. 함수 형식으로 사용되는데 Props를 입력으로 받아 React element를 출력하는 느낌으로 이해하면 된다. 객체지향의 클래스 및 인스턴스와 비슷한 개념을 가지고 있다.

     

    Component는 크게 Function Component와 Class Component로 나뉜다. 함수 컴포넌트는 pure 함수 같은 역할을 해야 하는데, props를 받아와 element를 출력한다. 클래스 컴포넌트는 React.Component를 상속받아서 새롭게 자식 클래스를 만드는 방법이다. Component 이름을 지을 때는 항상 대문자로 시작해야 한다. 그렇지 않을 시 DOM 팩(div, p ...)으로 인식할수도 있다.

    Props

    속성이라는 뜻을 가지고 있다. Component의 속성을 의미하는데, Props에 따라 출력되는 element가 달라진다. 컴포넌트에 전달할 다양한 정보를 담고 있는 자바스크립트 객체라고 보면 된다. 그리고 Read-Only 특성을 가지고 있다, 이는 값을 변경할 수 없음을 의미한다. 그래서 값이 바뀐다면 새롭게 element를 출력해야 한다. 모든 리액트 컴포넌트는 Props를 직접 수정할 수 없고, 같은 Props에 대해서는 항상 같은 결과를 보여줘야 한다.

    function App(props) {
        return (
            <Profile
                name = "cdd"
                introduction = "hi, i am cdd"
                viewCount = {1500}
            />
        )
    }

    각 속성에 값을 넣을 때 중괄호를 사용하는 경우는 자바스크립트 코드임을 의미한다. 자바스크립트 객체가 되어 Props로 값을 전달할 수 있다. jsx를 사용하지 않는다면 createElement() 함수를 사용하여야 한다. 이 부분은 그냥 참고만 하고 넘어가자.

    컴포넌트 합성

    function Welcome(props) {
        return <h1>Hello, {props.name}</h1>
    }
    
    function App(props) {
        return (
            <div>
                <Welcome name = "cdd"/>
                <Welcome name = "ion"/>
            </div>
        )
    }

    여러 개의 컴포넌트를 활용하여 하나의 컴포넌트를 만드는 것을 컴포넌트 합성이라고 한다. 반대로 컴포넌트 추출이라는 방법도 존재하는데,

    컴포넌트 추출

    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>
        )
    }

    1. Avatar 추출

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

    2. Avatar 컴포넌트 반영

    function Comment(props) {
        return (
            <div className="comment">
                <div className="user-info">
                    <Avatar user = {props.author} />
                    /* <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>
        )
    }

    3. user-info 추출

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

    4. Result

    function Comment(props) {
        return (
            <div className="comment">
                <div className="user-info">
                    <UserInfo 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>
        )
    }

    < Source />

    Comment.jsx

    import React from "react";
    
    const styles = {
        wrapper: {
            margin: 8,
            padding: 8,
            display: "flex",
            flexDirection: "row",
            border: "1px solid gray",
            borderRadius: 16
        },
        imageContainer: {},
        image: {
            width: 50,
            height: 50,
            borderRadius: 25,
        },
        contentContainer: {
            marginLeft: 8,
            display: "flex",
            flexDirection: "column",
            justifyContent: "center",
        },
        nameText: {
            color: "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

    CommentList.jsx

    import React from "react";
    import Comment from "./Comment";
    
    const comments = [
        {
            name: "CDD",
            comment: "I'm Videographer"
        },
        {
            name: "Neo Vincent",
            comment: "Thank you Corona"
        },
        {
            name: "ION",
            comment: "No Cap"
        }
    ]
    
    function CommentList(props) {
        return (
            <div>
                {comments.map((comment) => {
                    return (
                        <Comment name = {comment.name} comment = {comment.comment} />
                    );
                })}
            </div>
        )
    }
    
    export default CommentList

    ※ 본 게시글은 소플님의 강의 영상을 참고하여 작성되었습니다. 개인적인 공부 목적으로 사용하고 있고, 문제 시 비공개 전환하도록 하겠습니다.

    'Programming > ReactJS' 카테고리의 다른 글

    [ReactJS] Conditional Rendering  (0) 2022.11.30
    [ReactJS] Handling Events  (0) 2022.11.30
    [ReactJS] Hooks  (0) 2022.11.30
    [ReactJS] State and Lifecycle  (0) 2022.11.30
    [ReactJS] Rendering Elements  (0) 2022.11.29

    댓글