react 수업

5. components, props

gongmille 2024. 9. 2. 17:56

-components

자바스크립트의 함수와 비슷하다.

어떠한 속성값을 받아서 리액트 엘리먼트를 생성하여 리턴해 주는 것이다.

 

-props

property를 줄인 단어 prop + s 를 붙인 것.

컴포넌트에 들어가는 속성. 비유하자면 붕어빵 속 재료라고 보면 된다.

컴포넌트의 모습과 속성을 결정하는 것이 props다.

컴포넌트에 전달할 다양한 정보를 담고 있는 자바스크립트 객체.

 

-props 특징

읽기 전용 - 엘리먼트 생성 도중에는 값props을 변경할 수 없다.

 

-component 만들기

componrnt는 function component 와 class component가 있다.

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

function component : 간단한 코드인것이 장점

 

class Welcome extends React.Component{
	render() {
    	return <h1>안녕, {props.name}</h1>;
    }
}

class component : react.component를 상속받아서 만드는 것이 특징.

 

-component 이름은 항상 대문자로 시작해야한다. > 소문자로 쓰면 DOM태그(div, span 등)로 인식하기 때문.

 

-component 렌더링

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

const element = <Welcome name="인제" />;

<!--렌더링 호출-->
ReactDOM.render(
	element,
    document.getElementById('root');
);

 

렌더링을 호출하면 element가 파라미터값으로 들어간다.

그렇다면 element에 선언된 Welcome 이라는 컴포넌트가 불러지고 function Welcome의 props안에 element가 가지고 있는 값, <Welcome name="인제">에 선언되어 있는 속성 name="인제"가 들어가게 된다.

그리고 "인제"가 들어간 엘리먼트가 생성되어서 보여지게 된다.

 

-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 컴포넌트를 가지고 있고 그 안에 각기 다른 props값으로 각기 다른 엘리먼트가 생성되서 App 컴포넌트에 들어가진다.

그리고 해당 값이 ReactDOM.render를 통해 불러져 root에 보여진다.

 

-component 추출

복잡한 컴포넌트를 쪼개서 여러 개로 나누는 것. 잘 사용하면 재사용성이 높아진다.

 

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

 

props ={

 author: {name:"이름", avatarUrl:"https://..."},

 text : "내용",

 date : Date.now()

}

 

여기서 <img> 를 컴포넌트로 추출해본다면

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

이렇게 될 것이고 해당 부분을 적용한다면

 

...
	<div className="comment">
    	<div className="user-info">
        	<Avartar user={props.author} />
...

식으로 변경이 된다.

다른 태그들도 이런식으로 컴포넌트로 추출해서 변경할 수 있다.

 

추출은 되도록 기능단위로 구분하는 것이 좋고 나중에 재사용이 바로 가능한 형태로 추출하는 것이 좋다.

 

-실습

 

import React from "react";

function Comment(props){
    return (
        <div>
            <h1>첫번째 코맨트</h1>
        </div>
    );
}

export default Comment;

Comment.jsx

 

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

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

export default CommentList;

CommentList.jsx

 

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

import CommentList from './chapter05_component_props/CommentList';


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

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

// 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();

index.js

 

 

이번엔 무사히 한번에 보여졌다. 이제 여기에 스타일을 추가해보자.

 

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
    },
    conrtentContainer: {
        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="" style={styles.image}/>
            </div>

            <div style={styles.conrtentContainer}>
                <span style={styles.nameText}>Test01</span>
                <span style={styles.commentText}>첫번째 코멘트</span>
            </div>
        </div>
    );
}

export default Comment;

Comment.jsx

강의에서는 이미지 링크는 적었지만 귀찮기도 해서 그냥 생략했다.

 

적용시 위와같이 나온다.

 

이제 작성자 이름과 내용을 동적 변경이 가능하도록 props로 빼보자

 

...
 <div style={styles.conrtentContainer}>
                <span style={styles.nameText}>{props.name}</span>
                <span style={styles.commentText}>{props.comment}</span>
            </div>
...

comment.jsx 에서 test 01 과 첫번째 코멘트 라고 적혀있던 부분을 위와 같이 변경한다.

 

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

function CommentList(props){
    return(
        <div>
            <Comment name="test 01" comment="첫번째 코멘트"/>
            <Comment name="test 02" comment="두번째 코멘트"/>
        </div>
    );
}

export default CommentList;

CommentList.jsx

 

목록을 출력하는 부분을 위와 같이 변경을 해준다.

 

그럼 과 같이 표출이 된다.

 

데이터를 별도의 객체로 분리해서 표출해 보자

 

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

const comments = [
    {
        name : "tset 01",
        comment : "First Comment"
    },
    {
        name : "tset 02",
        comment : "Second Comment"
    },
    {
        name : "tset 03",
        comment : "Three Comment"
    }
];

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

export default CommentList;

CommentList.jsx

 

자바스크립트 배열의 map 함수를 써서 각 댓글 객체에 대하여 컴포넌트를 리턴하도록 한다.

(map 함수는 추후 배울 예정)

 

 

결과는 위와 같이 나온

'react 수업' 카테고리의 다른 글

7.hooks  (1) 2024.09.03
6.state와 lifecycle  (1) 2024.09.03
4. rendering elements  (0) 2024.08.31
3. jsx와 createElement  (0) 2024.08.31
2. react-react-app를 vs code에서 실행하기  (0) 2024.08.29