First met React (3)

sein lee·2023년 10월 13일
0
post-thumbnail
post-custom-banner

5강. Components and Props

1. Components와 Props의 정의

Components

레고 블록 조립하듯 컴포넌트들을 모아서 개발
React Component는 자바스크립트 함수와 비슷-> 입력(Props)을 받아 정해진 출력(React element)을 준다.

Props

Component의 속성(재료), 컴포넌트에 전달할 다양한 정보를 담고있는 자바스크립트 객체

2. Props의 특징 및 사용법

Props 특징

Read-Only : 값을 변경 할 수 없다.
새로운 값을 컴포넌트에 전달하여 새로운 Element를 생성, element 가 다시 렌더링

모든 리액트 컴포넌트는 그들의 Porps에 관해서는 Pure 함수 같은 역할을 해야한다.
= 모든 리액트 컴포넌트는 Props를 직접 바꿀 수 없고, 같은 Props에 대해서는 항상 같은 결과를 보여줄 것!

사용법

function App(props){
    return(
        <Profile
            name ="감자"
            introduction = "안녕하세요, 감자입니다."
            viewCount={1500}
        />
    );
}
  • Profile 컴포넌트에 name, introduction, viewCount라는 속성을 줌
  • 속성의 값을 넣을때 {} 중괄호의 유무가 중요
    - { } : 문자열 포함 모두가능
    - "" : 문자열만
function App(props){
    return(
        <Layout
            width = {2560}
            height ={1440}
            header={
                <Header title = "감자의 블로그입니다"/>
            }
            footer ={
                <Footer />
            }
        />
    );
}
  • props에 중괄호를 사용해서 컴포넌트도 사용할 수 있다

jsx 없이 작성 (참고만)

React.createElement(
    Profile,
    {
        name : "감자",
        introduction: "안녕하세요, 감자입니다",
        viewCount :1500
    },
    null
);

3. Component 만들기 및 렌더링

Component 만들기

Function Component

리액트 컴포넌트를 일종의 함수 처럼 본다.

function Welcome(props){
    return <h1>안녕, {props.name}</h1>;
}
  • props 객체를 받아서 React element를 return
  • 간단한 코드가 장점

Class Component

자바스크립트 ES6의 클래스를 사용하여 만든다.

class Welcome extends React.Component {
    render(){
        return <h1>안녕, {this.props.name}</h1>;
    }
}
  • React.Component를 상속받아서 만든다.

Component의 이름

Component의 이름은 항상 대문자로 시작해야한다.

// HTML div 태그로 인식
const element = <div />;
//Welcome 이라는 리액트 Component로 인식
const element = <Welcome name ="인제"/>;

Component 렌더링
가장 먼저 component로부터 element를 생성해야한다.

// DOM 태그를 사용한 element
const element = <div />;
//사용자가 정의한 Component를 사용한 element
const element = <Welcome name ="인제"/>;
//Welcome - 함수 컴포넌트
function Welcome(prop){
    return <h1>안녕, {props.name}</h1>;
}
const element = <Welcome name="인제"/>;
//"인제"라는 값을 가진 element를 파라미터로 해서 ReactDOM.redner 함수를 호출한다.
ReactDOM.redner(
    element,
    document.getElementById('root')
);
  • 리액트는 Welcome 컴포넌트에 name="인제" 라는 props를 넣어서 호출하고 그 결과로 React element가 생성됨 .
  • 최종적으로 생성된 element는 ReactDOM을 통해 실제 DOM에 효과적으로 업데이트 되고 화면에 출력된다.

4. Component 합성과 추출

Component 합성

Component안에 또 다른 Component를 쓸 수 있다.

function Welcome(prop){
    return <h1>안녕, {props.name}</h1>;
}
function App(props) {
    return (
        <div>
            <Welcome name = "Mike"/>
            <Welcome name = "Steve"/>
            <Welcome name = "Jane"/>
        </div>
    )
}

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

Component 추출

큰 Component에서 일부를 추출해서 새로운 Component를 만든다.

  • 재사용성 증가, 개발속도 상승

Comment 함수

function Comment(props) {
    return (
        <div className="comment">
            <div className="user-info">
                {/* 사용자의 프로핑 이미지를 img 태그를 사용하여 표시
                1. 이부분을 추출하여 avatar라는 컴포넌트로 생성 */}
                <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>
    );
}

Comment 함수의 props

props  = {
    author: {
        name: "감자",
        avatarUrl: "https://...",
    },
    text : "댓글입니다",
    date: Date.nomw(),
}

Comment 함수 추출해서 만들기

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

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

function Comment(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>
    );
}

5. 댓글 컴포넌트 만들기

<Comment.jsx>

import React from "react";

function Comment(props) {
    return (
        <div className="comment">
           <h1>제가 만든 첫 컴포넌트입니다.</h1>
        </div>
    );
}

export default Comment;

<CommentList.jsx>

import React from "react";
import Comment from "./Comment";

function CommentList(props) {
    return (
        <div>
            <Comment />
        </div>
    );
}

export default CommentList;

<index.js>

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

import Library from './chapter_03/Library';
import Clock from './chapter_04/Clock';
import CommentList from './chapter_05/CommentList';

ReactDOM.render(
  <React.StrictMode>
    <CommentList />
  </React.StrictMode>,
  document.getElementById('root')
);


// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

Comment Component에 스타일 입히기

<Comment.jsx>

import React from "react";

//Comment Component에 CSS 스타일 입히기
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,
    },
    constentContainer:{
        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.constentContainer}>
                <span style={styles.nameText}>감자</span>
                <span style={styles.commentText}>
                    제가 만든 첫 컴포넌트 입니다.
                </span>
            </div>
        </div>
    );
}

export default Comment

Comment Component에 Props 추가하기

<Commnet.jsx>에 해당부분 수정

  • 아무것도 나오지 않음 : name과 comment가 정의되지않아 undefined!

<CommentList.jsx>

import React from "react";
import Comment from "./Comment";

function CommentList(props) {
    return (
        <div>
            <Comment name ={"감자"} comment = {"안녕하세요, 감자입니다."}/>
        {/* <Comment name ={"고구마"} comment = {"안녕하세요, 고구마입니다."}/> */}
        </div>
    );
}

export default CommentList;

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

<CommentList.jsx>

import React from "react";
import Comment from "./Comment";

const comments =[
    {
        name : "감자",
        comment : "Hello"
    },
    {
        name : "고구마",
        comment : "Hi"
    },
    {
        name : "옥수수",
        comment : "Bye"
    },
];

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

export default CommentList;

profile
개발감자
post-custom-banner

0개의 댓글