본문 바로가기
> 메모/React

[리액트] - 데이터 바인딩 / 컴포넌트화 / props 활용 / map() 활용

by 자몽주스 2024. 5. 19.
728x90
반응형
다른 js 파일에 있는 html
state에 보관해 놓고 html에 데이터 바인딩하기
- export / import

data.js 에 있는 html 이 담긴 변수 data 를 App.js 로 옮기기
export default 변수명;  - 변수 1개 할 경우,
export {변수1, 변수2}; - 변수 2개 이상 할 경우 (default 사용 안함)
//data.js에 있는 것

let data = [
  {
    id: 0,
    title: "White and Black",
    content: "Born in France",
    price: 120000,
  },

  {
    id: 1,
    title: "Red Knit",
    content: "Born in Seoul",
    price: 110000,
  },

  {
    id: 2,
    title: "Grey Yordan",
    content: "Born in the States",
    price: 130000,
  },
];

export default data;

하단에

export default data;

변수명 넣어서 써준다.

변수, 함수, 자료형 전부 export 가능
import 해주기 - App.js 에다가 해줌.
import 작명 from "./경로";
import data from "./data.js";

./ 부터 경로 시작함.

state로 옮겨주기
  let [shoes] = useState(data);

{shoes} 중괄호 사용해서 써준다.

데이터 바인딩

자바스크립트 array / object 문서 참고

  <h4>{shoes[0].title}</h4>

이런 식으로 해주면 된다.


html 부분 컴포넌트로 만들기.
   <div className="col-md-4">
            <img
              src="https://codingapple1.github.io/shop/shoes1.jpg"
              width="80%"
            />
            <h4>{shoes[0].title}</h4>
            <p>상품정보</p>
          </div>
          <div className="col-md-4">
            <img
              src="https://codingapple1.github.io/shop/shoes2.jpg"
              width="80%"
            />
            <h4>상품명</h4>
            <p>상품정보</p>
          </div>
          <div className="col-md-4">
            <img
              src="https://codingapple1.github.io/shop/shoes3.jpg"
              width="80%"
            />
            <h4>상품명</h4>
            <p>상품정보</p>
          </div>

이 부분 컴포넌트화 하기.

- 반복돼서 나오기 때문

1) function 부터 만들기
function Card(){
  return (
    <div className="col-md-4">
      <img src="https://codingapple1.github.io/shop/shoes1.jpg" width="80%" />
      <h4>상품명</h4>
      <p>상품정보</p>
    </div>
  )
}

만들 때, App function 밖에서 만들기.

return 문 써 준 다음에 html 내용 넣어줌. 

= 소괄호 안에다가 축약할 html 을 담기

   <div className="container">
        <div className="row">
          <Card />
          <Card />
          <Card />
        </div>
      </div>

App function 안에 있던 html 부분

아까 만든 컴포넌트(<Card />)로 꽂아넣었음.

/*eslint-disable*/
import "bootstrap/dist/css/bootstrap.min.css";
import logo from "./logo.svg";
import "./App.css";
import { Button, Navbar, Container, Nav } from "react-bootstrap";
import { useState } from "react";
import data from "./data.js";

function App() {
  let [shoes, setShoes] = useState(data);

  return (
    <div className="App">
      <Navbar bg="dark" variant="dark">
        <Container>
          <Navbar.Brand href="#home">Navbar</Navbar.Brand>
          <Nav className="me-auto">
            <Nav.Link href="#home">Home</Nav.Link>
            <Nav.Link href="#features">Features</Nav.Link>
            <Nav.Link href="#pricing">Pricing</Nav.Link>
          </Nav>
        </Container>
      </Navbar>
      {/* 대문배경 만들기 */}
      <div className="main-bg"></div>
      <div className="container">
        <div className="row">
          <Card />
          <Card />
          <Card />
        </div>
      </div>
    </div>
  );
}
function Card() {
  return (
    <div className="col-md-4">
      <img src="https://codingapple1.github.io/shop/shoes1.jpg" width="80%" />
      <h4>상품명</h4>
      <p>상품정보</p>
    </div>
  );
}
export default App;

전체 파일 보면 이렇게 돼있다. 

 

다시 상품명하고, 상품정보 데이터 바인딩하려면

shoes state App function 에는 있지만

Card function 에는 없으므로

props 써서 데이터바인딩 해줘야함.

컴포넌트 쓴 곳에 가서 props로 보낼 state 작명(shoes)먼저 해주기. 
  <Card shoes={shoes} />
컴포넌트 function 으로 가서 파라미터로 props 등록
function Card(props) {
  return (
    <div className="col-md-4">
      <img src="https://codingapple1.github.io/shop/shoes1.jpg" width="80%" />
      <h4>상품명</h4>
      <p>상품정보</p>
    </div>
  );
}

등록해주고

function Card(props){
  return (
    <div className="col-md-4">
      <img src="https://codingapple1.github.io/shop/shoes1.jpg" width="80%" />
      <h4>{ props.shoes[0].title }</h4>
      <p>{ props.shoes[0].price }</p>
    </div>
  )
}

다시 아까와 같이 데이터 바인딩 해준다.

같은 사진과 같은 제목, 같은 값이 나올 것. 


컴포넌트를 매번 다르게 보여주게 하기
- 카드 컴포넌트를 여러개 만드는 방법도 있지만,
props 를 잘 조절해주기. 
- props 에 인덱스 붙이기

 

        <div className="row">
          <Card shoes={shoes} />
          <Card shoes={shoes} />
          <Card shoes={shoes} />
        </div>

이 부분을

        <div className="row">
          <Card shoes={shoes[0]} />
          <Card shoes={shoes[1]} />
          <Card shoes={shoes[2]} />
        </div>

이렇게 array 인덱스를 추가해줘서 매번 다르게 보여줄 수 있도록 만듦.

function Card(props){
  return (
    <div className="col-md-4">
      <img src="https://codingapple1.github.io/shop/shoes1.jpg" width="80%" />
      <h4>{ props.shoes.title }</h4>
      <p>{ props.shoes.price }</p>
    </div>
  )
}

컴포넌트 부분도 인덱스 삭제시키고 수정해준다.


궁금했던 점) 
Card 컴포넌트에 shoes 배열 전체를 전달하는 것과,
인덱스를 사용하여 shoes 배열의 특정 요소를 전달하는 것의 차이
  • <Card shoes={shoes} />와 같이 shoes 전체 배열을 전달하면, Card 컴포넌트는 배열 전체를 props로 받게 됩니다.
  • <Card shoes={shoes[0]} />와 같이 인덱스를 붙이면 shoes 배열의 특정 요소만 전달하게 됩니다.

props 사용을 위해 원래 

<Card shoes={shoes} />
<Card shoes={shoes} />
<Card shoes={shoes} />

이거에서

        <Card shoes={shoes[0]} />
          <Card shoes={shoes[1]} />
          <Card shoes={shoes[2]} />

이렇게 바꿀 수 있는 건지 의문이 듦.

shoes 배열의 각 항목을 개별적으로 Card 컴포넌트에 전달하려면
인덱스를 사용하여 해당 요소를 지정할 수 있습니다

shoes배열을 가져와 각 Card 컴포넌트에 개별 요소를 전달 .
전체 배열을 전달할 때
<Card shoes={shoes} />
이 경우 shoes 배열 전체가 Card컴포넌트에 전달됨. 
Card컴포넌트 내에서 props.shoes 는 배열 전체를 가리키게 된다.
인덱스를 사용하여 특정 요소를 전달할 때
<Card shoe={shoes[0]} />는 shoes 배열의 첫 번째 요소를 전달
<Card shoe={shoes[1]} />는 두 번째 요소를 전달
<Card shoe={shoes[2]} />는 세 번째 요소를 전달
이를 통해서, Card 컴포넌트는 shoes 배열의 개별 데이터를 사용하게 된다.

"props 활용하면 매번 다른 내용의 모달창 맘대로 만들 수 있다"


똑같은 상품 사진 수정시키기
<img src="https://codingapple1.github.io/shop/shoes1.jpg" width="80%" />

이런 식으로 하드코딩 돼있는 이미지 수정하기

= props 사용

<Card shoes={shoes[0]} i={1} />
<Card shoes={shoes[1]} i={2} />
<Card shoes={shoes[2]} i={3} />

props 활용해서 숫자를 보냄.

props로 숫자, 문자열, 객체 등 다양한 데이터를 보낼 수 있다
props는 부모 컴포넌트가 자식 컴포넌트에게 데이터를 전달하기 위한 메커니즘이다.
부모 컴포넌트가 자식 컴포넌트에 값을 전달할 때 props를 사용한다.
 i 라는 숫자 값을 Card컴포넌트에 전달하는 방법
<Card shoes={shoes[0]} i={1} />
<Card shoes={shoes[1]} i={2} />
<Card shoes={shoes[2]} i={3} />​
App컴포넌트에서
Card컴포넌트를 사용할 때,
shoes 와 함께
i 라는 숫자 값을 props로 전달
  • <Card shoes={shoes[0]} i={1} />에서는 shoes 배열의 첫 번째 요소와 숫자 1을 전달합니다.
  • <Card shoes={shoes[1]} i={2} />에서는 두 번째 요소와 숫자 2를 전달합니다.
  • <Card shoes={shoes[2]} i={3} />에서는 세 번째 요소와 숫자 3을 전달합니다.
  • props.i는 부모 컴포넌트로부터 전달받은 숫자 값을 가리킵니다.

map 함수 활용 
          <Card shoes={shoes[0]} i={1} />
          <Card shoes={shoes[1]} i={2} />
          <Card shoes={shoes[2]} i={3} />

이렇게 반복되는 부분 

map 함수 활용해보기.

(카드 데이터 개수마다 반복되도록)

shoes 라는 state 개수가 변할 때마다, 안에있는 코드를 변화시켜줘야 함. 

  {/* map 함수 */}
          {shoes.map((a, i) => {
            // 컴포넌트 여기에 사용
            return <Card shoes={shoes[i]} i={i}></Card>;
          })}

대괄호 써주고 map 함수 만들어주기.

 <div className="row">
                  {shoes.map((a, i) => {
                    return <Card shoes={shoes[i]} i={i} key={i}></Card>;
                  })}
                </div>

이렇게 해주면 된다.

  <img
        src={
          "https://codingapple1.github.io/shop/shoes" + (props.i + 1) + ".jpg"
        }
        width="80%"
      />

이미지 부분은

i + 1 이렇게 설정.

 

728x90
반응형