Front/React

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

oodada 2023. 10. 29. 17:17

1. Props(Properties) 란?

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

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

이미지 출처

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
function App() {
  return (
    <div id="wrap">
      <Header title="Dashboard" />
      <main>
        <Section
          title="Home"
          desc="홈 페이지."
        />
        <Section
          title="About"
          desc="소개 페이지"
        />
        <Section
          title="SignIn"
          desc="로그인 페이지"
        />
      </main>
      <Footer />
    </div>
  );
}

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

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

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

export default App;

- Nav Props

  • 위 예제에서 Nav 컴포넌트만 정리를 해보면...
  • Nav 컴포넌트에 li 배열을 사용하여 nav를 구성할 수 있다.
// App.js
function Nav() {
  //  nav의 항목이 추가될 때마다 코드를 수정해야 하기 때문에 비효율적이다.
  const navArr = [
    <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
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
티스토리 친구하기