Front/React

속성(Props, Properties) - React 배우기

oodada 2023. 10. 29. 17:17
반응형

1. Props(Properties) 란?

  • 컴포넌트의 속성을 설정할 때 사용하는 요소이다.
  • 컴포넌트에게 전달되는 데이터를 의미한다.

Components로 고양이를 계속 만들어낼 수 있다면...
Props로 서로 다른 고양이를 만들어낼 수 있다.

이미지 출처 : https://javascript.plainenglish.io/basic-react-components-and-props-for-showing-lots-of-cats-d41bf67cc26

2. Props의 특징

  • 컴포넌트의 속성(props)은 컴포넌트를 사용할 때 설정하는 속성
  • 컴포넌트의 속성은 부모 컴포넌트에서 설정할 수 있다.
  • 컴포넌트 내부에서는 설정할 수 없음
  • {}를 사용하여 자바스크립트 표현식을 속성 값으로 설정할 수 있음

- Props.children (props.속성이름)

  • 컴포넌트 태그 사이에 작성한 내용을 조회할 때 사용한다.
  • 컴포넌트 태그 사이에 작성한 내용은 props.children이라는 props로 전달된다.
// App.js
import React from 'react'

function App() {
    return (
        <div className="root">
            <Cat name="고양이1" age="1" />
            <Cat name="고양이2" age="2" />
            <Cat name="고양이3" age="3" />
        </div>
    )
}

function Cat(props) {
    console.log(props)
    // const props = {name: "고양이1", age: "1"}
    // props.name = 고양이1, 고양이2, 고양이3
    // props.age = 1, 2, 3
    return (
        <div>
            <h2>
                고양이 이름은 {props.name}이고 나이는 {props.age} 입니다.
            </h2>
        </div>
    )
}

export default App

3. Props 사용

https://oddcode.tistory.com/254
React 배우기 - 컴포넌트(Components) 에서 사용한 예제를 Props를 사용하여 수정해보자.

- Haeader, Article Props

  • Header 컴포넌트에 속성(props)을 사용하여 동적으로 title을 구성할 수 있다.
  • Article 컴포넌트에 속성(props)을 사용하여 동적으로 title, body를 구성해 중복사용을 줄일 수 있다.
// App.js
import React from 'react';

function App() {
  return (
    <div className="root">
      <Header title="Dashboard" />

      <Nav />

      <Article title="Home" desc="홈 페이지입니다." />
      <Article title="About" desc="소개 페이지입니다." />
      <Article title="SignIn" desc="로그인 페이지입니다." />
    </div>
  );
}

function Header(props) {
  console.log(props); // const props = {title: "Dashboard"} 와 같다.
  return (
    <header>
      <h1>{props.title} </h1>
    </header>
  )
}

... Nav 컴포넌트 생략 ...

function Article(props) {
  return (
    <div>
      <h2>{props.title}</h2>
      <p>{props.desc}</p>
    </div>
  );
}

export default App;

- Nav Props

  • 위 예제에서 Nav 컴포넌트만 정리를 해보면...
  • Nav 컴포넌트에 li 배열을 사용하여 nav를 구성할 수 있다.
// App.js
import React from 'react'

function App() {
    return (
        <div className="root">
            <Nav />
        </div>
    )
}

function Nav() {
    //  nav의 항목이 추가될 때마다 코드를 수정해야 하기 때문에 비효율적이다.
    const list = [
        <li>
            <a href="/">Home</a>
        </li>,
        <li>
            <a href="/">About</a>
        </li>,
        <li>
            <a href="/">SignIn</a>
        </li>,
    ]
    return (
        <nav>
            <ul>{list}</ul>
            {/* 문자열이 아닌 데이터를 받을 땐 {}로 깜싸주어야 한다. */}
        </nav>
    )
}

export default App
  • Nav 컴포넌트에 반복문과 push 메소드, 속성(props)을 사용하여 동적으로 nav를 구성할 수 있다.
  • for(초기값; 조건식; 증감식) { ... }
  • push() 메소드는 배열의 끝에 요소를 추가한다.
// App.js
import React from 'react'

function App() {
    // nav를 배열로 구성한다.
    const navArr = [{ title: 'Home' }, { title: 'About' }, { title: 'SignIn' }]
    return (
        // nav를 props로 전달한다.
        <div className="root">
            <Nav nav={navArr} />
        </div>
    )
}

function Nav(props) {
    // prop로 전달된 nav를 받아서 동적으로 li를 구성한 다음 배열에 담아준다.
    const list = []
    // props.nav.length = 3
    for (let i = 0; i < props.nav.length; i++) {
        // list 배열에 li를 추가한다.
        list.push(
            // li에 key를 추가해 주는 이유는 리액트가 배열의 요소를 추가, 삭제, 수정할 때 효율적으로 처리하기 위해서이다.
            // props.nav[i].title = Home, About, SignIn
            <li key={props.nav[i]}>
                <a href="/">{props.nav[i].title}</a>
            </li>
        )
    }

    return (
        // ul 태그 안에 list 배열을 넣어준다.
        <nav>
            <ul>{list}</ul>
        </nav>
    )
}

export default App
  • 효율적인 방법으로 nav를 구성하기 위해 map() 함수를 사용할 수 있다.
  • map() 함수는 배열의 요소를 하나씩 꺼내서 반복문을 실행한다.
  • map((item, index) => { return ... }) 형태로 사용한다.
import React from 'react'

function App() {
    const navArr = [{ title: 'Home' }, { title: 'About' }, { title: 'SignIn' }]
    return (
        <div className="root">
            <Nav nav={navArr} />
        </div>
    )
}

function Nav(props) {
    // prop로 전달된 nav를 받아서 동적으로 li를 구성한 다음 배열에 담아준다.
    // map((item, index) => { return ... }) 형태로 사용한다. item = 배열의 요소, index = 0, 1, 2
    const list = props.nav.map((item, index) => (
        // item.title = Home, About, js
        // index = 0, 1, 2
        <li key={index}>
            <a href="/">{item.title}</a>
        </li>
    ))

    return (
        <nav>
            <ul>{list}</ul>
        </nav>
    )
}

export default App
  • map()을 return() 내부에서 사용할 수 있다.
import React from 'react'

function App() {
    const navArr = [{ title: 'Home' }, { title: 'About' }, { title: 'SignIn' }]
    return (
        <div className="root">
            <Nav nav={navArr} />
        </div>
    )
}

function Nav(props) {
    return (
        <nav>
            <ul>
                {props.nav.map((item, index) => (
                    <li key={index}>
                        <a href={'/sub/' + item.title}>{item.title}</a>
                    </li>
                ))}
            </ul>
        </nav>
    )
}

export default App
  • Nav 컴포넌트를 Header 컴포넌트에 포함시켜 props를 전달할 수 있다.
// App.js
import React from 'react'

function App() {
    const navArr = [{ title: 'Home' }, { title: 'About' }, { title: 'SignIn' }]
    return (
        <div className="root">
            <Header title="Dashboard" nav={navArr} />
        </div>
    )
}

function Header(props) {
    return (
        // props.nav = navArr
        <header>
            <h1>{props.title}</h1>
            <Nav nav={props.nav} />
        </header>
    )
}

function Nav(props) {
    return (
        <nav>
            <ul>
                {props.nav.map((item, index) => (
                    <li key={index}>
                        <a href={'/sub/' + item.title}>{item.title}</a>
                    </li>
                ))}
            </ul>
        </nav>
    )
}

export default App
  • 위 코드를 구조분해 할당을 사용하여 수정해보자.
// App.js
import React from 'react'

function App() {
    const navArr = [{ title: 'Home' }, { title: 'About' }, { title: 'SignIn' }]
    return (
        <div className="root">
            <Header title="리액트(React)" nav={navArr} />
        </div>
    )
}

function Header({ title, nav }) {
    // 구조분해 할당을 사용하여 props를 분리한다.
    // const { title, nav } = props;
    return (
        <header>
            <h1>{title}</h1>
            <Nav nav={nav} />
        </header>
    )
}

function Nav({ nav }) {
    // const { nav } = props;
    return (
        <nav>
            <ul>
                {nav.map((item, index) => (
                    <li key={index}>
                        <a href={'/sub/' + item.title}>{item.title}</a>
                    </li>
                ))}
            </ul>
        </nav>
    )
}

export default App

4. Props 사용 예제

- Table Props

  • Table 컴포넌트에 속성(props)을 사용하여 동적으로 table을 구성할 수 있다.
// App.js
import React from 'react'

function App() {
    // data를 배열로 구성한다.
    const dataArr = [
        { name: '홍길동', age: 20 },
        { name: '임꺽정', age: 25 },
        { name: '전우치', age: 30 },
    ]
    return (
        <div className="root">
            <Table data={dataArr} /> {/* data를 props로 전달한다. */}
        </div>
    )
}

function Table(props) {
    // key를 추가해 주는 이유는 리액트가 배열의 요소를 추가, 삭제, 수정할 때 효율적으로 처리하기 위해서이다.
    // item.id = 1, 2, 3
    // item.name = 홍길동, 임꺽정, 전우치
    // item.age = 20, 25, 30

    return (
        <table>
            <thead>
                <tr>
                    <th>id</th>
                    <th>name</th>
                    <th>age</th>
                </tr>
            </thead>
            <tbody>
                {props.data.map((item, index) => (
                    <tr key={index}>
                        <td>{index + 1}</td>
                        <td>{item.name}</td>
                        <td>{item.age}</td>
                    </tr>
                ))}
            </tbody> {/* list 배열을 넣어준다. */}
        </table>
    )
}

export default App

- Comment Props (복합 컴포넌트)

// App.js
import React from 'react'

const App = () => {
    const user1 = {
        name: 'winter',
        avatarUrl: 'https://assets.chatgpt4google.com/assets/promo/43.gif',
    }

    const user2 = {
        name: 'fall',
        avatarUrl: 'https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png',
    }

    const commentData1 = {
        user: user1,
        text: 'This is a comment from winter.',
        date: '2023.10.10',
    }

    const commentData2 = {
        user: user1,
        text: 'This is a comment from fall.',
        date: '2023.11.23',
    }

    // Comment 컴포넌트에 commentData를 props로 전달한다.
    // 부모 컴포넌트에서 props로 전달한 데이터는 Comment 컴포넌트에서 props로 받아서 사용한다.
    return (
        <>
            <Comment data={commentData1} />
            <Comment data={commentData2} />
        </>
    )
}

const Comment = (props) => {
    // props.data = commentData1, commentData2

    // props.data.user = users[0], users[1]
    // props.data.text = 'This is a comment from winter.', 'This is a comment from fall.'
    // props.data.date = '2023.10.10', '2023.11.23'
    return (
        <div>
            <UserInfo user={props.data.user} />
            <div>{props.data.text}</div>
            <div>{props.data.date}</div>
        </div>
    )
}

const UserInfo = (props) => {
    // props.user = user1, user2

    // props.user.name = winter, fall
    return (
        <div>
            <img src={props.user.avatarUrl} alt={props.user.name} />
            <div>{props.user.name}</div>
        </div>
    )
}

export default App
  • map() 함수를 사용하여 Comment 컴포넌트 배열을 생성할 수 있다.
import React from 'react'

const App = () => {
    const users = [
        {
            name: 'winter',
            avatarUrl: 'https://assets.chatgpt4google.com/assets/promo/43.gif',
        },
        {
            name: 'fall',
            avatarUrl: 'https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png',
        },
    ]

    const comments = [
        {
            user: users[0],
            text: 'This is a comment from winter.',
            date: '2023.10.10',
        },
        {
            user: users[1],
            text: 'This is a comment from fall.',
            date: '2023.11.23',
        },
    ]

    return (
        <>
            {comments.map((item, index) => (
                // index = 0, 1
                // item = comments[0], comments[1] 순서대로 배열의 요소를 꺼낸다.
                <Comment key={index} data={item} />
            ))}
        </>
    )
}

const Comment = (props) => {
    // props.data = commentData1, commentData2

    // props.data.user = users[0], users[1]
    // props.data.text = 'This is a comment from winter.', 'This is a comment from fall.'
    // props.data.date = '2023.10.10', '2023.11.23'
    return (
        <div>
            <UserInfo user={props.data.user} />
            <div>{props.data.text}</div>
            <div>{props.data.date}</div>
        </div>
    )
}

const UserInfo = (props) => {
    // props.user = user1, user2

    // props.user.name = winter, fall
    return (
        <div>
            <img src={props.user.avatarUrl} alt={props.user.name} />
            <div>{props.user.name}</div>
        </div>
    )
}

export default App

- Product Props (복합 컴포넌트)

import React from 'react'

const App = () => {
    const productsArr = [
        { id: 1, name: 'Product A', price: 10.99 },
        { id: 2, name: 'Product B', price: 15.99 },
        { id: 3, name: 'Product C', price: 7.49 },
    ]

    return (
        <div>
            <h1>Product List</h1>
            <ProductList products={productsArr} />
        </div>
    )
}

const ProductList = (props) => {
    // props.products = productsArr
    return (
        // product.id = 1, 2, 3
        // product = productsArr[0], productsArr[1], productsArr[2]
        <ul>
            {props.products.map((product) => (
                <Product key={product.id} product={product} />
            ))}
        </ul>
    )
}

const Product = (props) => {
    // props.product = productsArr[0], productsArr[1], productsArr[2]
    // props.product.name = Product A, Product B, Product C
    // props.product.price = 10.99, 15.99, 7.49
    // toFixed(2) = 소수점 2자리까지 표시한다.
    return (
        <li>
            <h3>{props.product.name}</h3>
            <p>Price: ${props.product.price.toFixed(2)}</p>
        </li>
    )
}

export default App
반응형

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

상태(State) - React 배우기  (0) 2023.10.31
이벤트(Event) - React 배우기  (0) 2023.10.31
React에서 GSAP 사용하기  (0) 2023.10.27
리액트 ES6 문법 정리  (0) 2023.10.27
React Table Data  (0) 2023.10.19
티스토리 친구하기