도리쓰에러쓰

[React] 반복문(map())을 이용하여 컴포넌트(Component) 반복 출력하기 본문

코딩애플 (React)/기초수업 (코딩애플) - 2

[React] 반복문(map())을 이용하여 컴포넌트(Component) 반복 출력하기

강도리 2022. 1. 10. 14:42

지난 게시물을 통해 App.js로 가져온 데이터를 이용해 컴포넌트(Component) 안에 출력시켜 보도록 하겠습니다.

 

[React] Export(내보내기) 및 Import(가져오기)

1. Export (내보내기) 더보기 export default [변수명] 변수 2개 export 하고 싶을 때 let name = 'Kim'; let name2 = 'Park'; export { name, name2 } 2. Import(가져오기) 더보기 import [변수명] from [경로]..

dori-coding.tistory.com


* 다음 코드에서 데이터를 활용해 Component에 출력하겠습니다.

/* eslint-disable */
import React, { useState } from 'react'
import { Navbar, Container, Nav, NavDropdown, Button } from 'react-bootstrap';
import './App.css';
import data from './data.js';

function App() {

  let [products, setProducts] = useState(data);

  return (
    <div className="App">
      <Navbar bg="light" expand="lg">
        <Container>
          <Navbar.Brand href="#home">Saint Laurent</Navbar.Brand>
          <Navbar.Toggle aria-controls="basic-navbar-nav" />
          <Navbar.Collapse id="basic-navbar-nav">
            <Nav className="me-auto">
              <Nav.Link href="#home">Home</Nav.Link>
              <Nav.Link href="#link">Link</Nav.Link>
              <NavDropdown title="Dropdown" id="basic-nav-dropdown">
                <NavDropdown.Item href="#action/3.1">Action</NavDropdown.Item>
                <NavDropdown.Item href="#action/3.2">Another action</NavDropdown.Item>
                <NavDropdown.Item href="#action/3.3">Something</NavDropdown.Item>
                <NavDropdown.Divider />
                <NavDropdown.Item href="#action/3.4">Separated link</NavDropdown.Item>
              </NavDropdown>
            </Nav>
          </Navbar.Collapse>
        </Container>
      </Navbar>
      
      <div className='Jumbotron'>
        <h1>20% Season Off</h1>
        <p>
          This is a simple hero unit, a simple jumbotron-style component for calling
          extra attention to featured content or information.
        </p>
        <p>
          <Button variant="primary">Learn more</Button>
        </p>
      </div>

    </div>
  );
}

export default App;


1. Component 출력하기

* Card라는 Component를 생성하기

function Card(props) {
  return(
    <div className='col-md-4'>
      <img className="img" src="images/img1.jpg" />
      <h4>{ props.products.title }</h4>
      <p>{ props.products.content }</p>
      <p>{ props.products.price }</p>
    </div>
  )
}

 

* Component 작성하여 출력

<div className='container'>
	<div className='row'>
		<Card products={products[0]}/>
		<Card products={products[1]}/>
		<Card products={products[2]}/>
	</div>
</div>

다음과 같이 출력되는 것을 확인할 수 있지만, 컴포넌트(Component)를 3줄 작성하는 것이 보기에 좋지 않기 때문에 반복문(map())을 통해 컴포넌트(Component)를 출력하겠습니다.


2. 반복문(map())을 이용하여 컴포넌트(Component) 출력하기

* map() 함수 이용하기

<div className='container'>
        <div className='row'>
          {
            products.map((a, i) => {
              return <Card products={a} num={i} key={i}/>
              // return <Card products={products[i]} num={i} key={i}/>
            })
          }
        </div>
      </div>
  • 자료.map( () => {} )
  • return(반복시킬 HTML) 
  • 변수 a에는 데이터가 들어오고, 변수 i에는 그 데이터의 num이 들어옵니다.
  • prop 중에 key를 작성하지 않으면 경고 메세지가 떠 작성하였습니다.

 

* props로 데이터 받아 Component에 데이터 넣기

function Card(props) {
  return(
    <div className='col-md-4'>
      <img className="img" src={ 'images/img'+ (props.num + 1) +'.jpg' } />
      <h4>{ props.products.title }</h4>
      <p>{ props.products.content }</p>
      <p>{ props.products.price }</p>
    </div>
  )
}

다음과 같이 하나의 Component로 map()을 활용해 여러개의 데이터를 출력된 것을 확인할 수 있습니다.


전체 코드

 

App.js

/* eslint-disable */
import React, { useState } from 'react'
import { Navbar, Container, Nav, NavDropdown, Button } from 'react-bootstrap';
import './App.css';
import data from './data.js';

function App() {

  let [products, setProducts] = useState(data);

  return (
    <div className="App">
      <Navbar bg="light" expand="lg">
        <Container>
          <Navbar.Brand href="#home">Saint Laurent</Navbar.Brand>
          <Navbar.Toggle aria-controls="basic-navbar-nav" />
          <Navbar.Collapse id="basic-navbar-nav">
            <Nav className="me-auto">
              <Nav.Link href="#home">Home</Nav.Link>
              <Nav.Link href="#link">Link</Nav.Link>
              <NavDropdown title="Dropdown" id="basic-nav-dropdown">
                <NavDropdown.Item href="#action/3.1">Action</NavDropdown.Item>
                <NavDropdown.Item href="#action/3.2">Another action</NavDropdown.Item>
                <NavDropdown.Item href="#action/3.3">Something</NavDropdown.Item>
                <NavDropdown.Divider />
                <NavDropdown.Item href="#action/3.4">Separated link</NavDropdown.Item>
              </NavDropdown>
            </Nav>
          </Navbar.Collapse>
        </Container>
      </Navbar>
      
      <div className='Jumbotron'>
        <h1>20% Season Off</h1>
        <p>
          This is a simple hero unit, a simple jumbotron-style component for calling
          extra attention to featured content or information.
        </p>
        <p>
          <Button variant="primary">Learn more</Button>
        </p>
      </div>
      
      <div className='container'>
        <div className='row'>
          {
            products.map((a, i) => {
              return <Card products={a} num={i} key={i}/>
            })
          }
        </div>
      </div>
    </div>
  );
}

function Card(props) {
  return(
    <div className='col-md-4'>
      <img className="img" src={ 'images/img'+ (props.num + 1) +'.jpg' } />
      <h4>{ props.products.title }</h4>
      <p>{ props.products.content }</p>
      <p>{ props.products.price }</p>
    </div>
  )
}

export default App;

 

data.js

export default [
    {
        id : 0,
        title : "Black Jacket",
        content : "Born in Paris",
        price : 6000000
    },

    {
        id : 1,
        title : "White Bag",
        content : "Born in Paris",
        price : 5000000
    },

    {
        id : 2,
        title : "Black Bag",
        content : "Born in Paris",
        price : 4000000
    },
]

 

App.css

.App {
  text-align: center;
}

.App-logo {
  height: 40vmin;
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .App-logo {
    animation: App-logo-spin infinite 20s linear;
  }
}

.Jumbotron {
  background-color: #EBECF0;
  height: 200px;
  padding-top: 25px;
  background-image: url('./background.jpg');
  background-size: cover;
  color: #FAFAFA;
}

.img {
  position: relative;
  width: 80%;
  height: 300px;
}

.App-header {
  background-color: #282c34;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: calc(10px + 2vmin);
  color: white;
}

.App-link {
  color: #61dafb;
}

@keyframes App-logo-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

 

index.html

 * <head> 안에 BootStrap 코드 추가 !!

<link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
      integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"
      crossorigin="anonymous"
/>
Comments