본문 바로가기
2222
Stack & Tool/React

react.js로 영화 웹 서비스 만들기 -2 [컴포넌트 만들기~]

by PARK TAE JOON 2021. 7. 2.

컴포넌트 만들기

potato.js 파일을 만들고
내부에 아래와 같이 소스를 작성한다.

import React from 'react'; // 최신 버전 리액트에서는 사용하지 않아도 되는 듯 하나 구 버전에서는 이렇게 작동했으므로 일단 쓴다.

function Potato() { // 대문자로 Potato를 써줬다.
    return ( // return 으로 시작하는 것 기억하자.
        <h3>this is new component</h3>
    )
}

export default Potato; // 컴포넌트를 선언해줬으면 밖에서 사용할 수 있게 해야한다.

혹은 potato.js 파일을 따로 만들지 않고
이렇게 할수도 있다.
즉, 컴포넌트를 한 파일안에 두개를 만든 것이다.
이렇게 하면 index.js에서 만 해도 두가지 컴포넌트를 불러오는 것이 된다.

import React from 'react';

function potato() {
    return <h1> potato </h1>
}

function App() {
    return (
        <div>
            <h1>hello</h1>
            <Potato />
        </div>    
    )
}

새로 만든 컴포넌트 추가하기

리액트가 최신버전이 되면서 원래 안됬던 것들이 되는 듯 하다.
무슨소리냐면 index.js에서 아래와 같았다고 했을 때
두 개의 컴포넌트를 인접하게 사용하지 못했었는데 지금은 된다.

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import Potato from './Potato';

ReactDOM.render(
  <React.StrictMode>
    <App /><Potato />
  </React.StrictMode>,
  document.getElementById('root')
);

예전에 안됬을 때는 그럼 어떻게 했을까?

아래와 같은 식으로 다른 컴포넌트가 선언된 위치에 컴포넌트를 끼어 넣었다.

import React from 'react';
import Potato from './Potato'

function App() {
  return (
    <div>
      <h1>hello</h1>
      <Potato />
    </div>

  );
}

export default App;

이것이 JSX의 절반이라고 보면 된다.
다시 한번 jsx란. javascript안의 html이다.
여기까지 와보니 JSX와 컴포넌트의 명확한 개념 공부가 더 하고싶어졌다. 다음 글에서 좀 더 알아보자.


props를 이용해서 컴포넌트 다루기

첫번째

function Food(props){
    return i like {props.name}
}

function App() {
    return (
        <div>
            <h1>hello</h1>
            <Food fav="kimchi" />
        </div>
    );
}

두번째

function Food({fav}){
    return i like {fav}
}

function App() {
    return (
        <div>
            <h1>hello</h1>
            <Food fav="kimchi" />
        </div>
    )
}

연습 프로젝트

api를 받아왔다고 가정하고 내가 직접 api처럼 배열을 만들어서 안에 데이타를 임의로 만든다.
다음 그 배열에 있는 데이터를 받아오면서 동적으로 출력되는 것을 만들어 보자.


const foodApi = [
    {
      name : "kimchi",
      image : "링크주소"
    },
    {
      name : "kkakdugi",
      image : "링크주소"
    },
    {
      name : "jjajang",
      image : "링크주소"
    }
]

function Food({name, image}){
    return <div>
        <h1>i like + {name}</h1>
        <img src={image}></img>
    </div>
}

function App() {
    return (
        <div>
            <h1>hello</h1>
            {foodApi.map(dish =>
                <Food name={dish.name} image={dish.image} />
            )}
        </div>
    )
}

이거를 변형시켜 볼 수 있다.

api 코드를 제와한 두 개만 가져와서 확인해본다.
이런식으로도 가능하다는 것을 보여줬을 뿐 가독성이나 효율성은 더 좋지 않다. 오히려 함수 수가 늘어났기 때문이다.
이건 이렇게 되는구나만 알자.


function Food({name, image}){
    return <div>
        <h1>i like {name}<h1>
        <img src={image}></img>
        </div>
}

function renderFood{dish => {
    return <Food name={dish.name} image={dish.image} />
})


function App() {
    return (
        <div>
            <h1> hello </h1>
            {foodApi.map(renderFood)}
        </div>
    )
}

console창을 보면 오류하나를 찾을 수 있다.

warning : Each child in a list should have a unique "key" prop.
각 리스트 내의 child는 유니크한 key prop를 가져야 한다고 한다.
api에 각 key값을 주고 food 컴포넌트를 제외하고 app 컴포넌트에서만 key값을 정해주면 해결된다!
오류가 해결됬다!

왜 이렇게 해야될까? 간단히 이해하면 리액트는 똑똑하지 않아서 foodILIke api들을 Food 컴포넌트로 읽어올 때 우리는 다르다는 걸 알지만 react는 구분할 수 없다. 그래서 리액트 내부적으로 이해할 수 있도록 key값을 정해준다. 하지만 Food 컴포넌트에서 볼 수 있듯 우리가 직접 사용하지는 않는다. 오직 리액트만을 위해서 사용한다.

import React from 'react';

const foodILike = [
  {
    id : 1,
    name : "Kimchi",
    image : "http://image.dongascience.com/Photo/2016/11/14787526584108[1].jpg"
  },
  {
    id : 2,
    name : "Kkakdugi",
    image : "https://shop.hansalim.or.kr/im/is/activeDesigner/100101004_content1.jpg"
  },
  {
    id : 3,
    name : "Jjajangmyun",
    image : "https://shop.hansalim.or.kr/im/is/activeDesigner/100101004_content1.jpg"
  }
]
function Food({name, image}) {     // props.fav 와 {fav}는 같은 것이다. ES6 문법이다.
                           //  return <h1>i like {props.fav}</h1>
  return <div>
      <h2>i like {name}</h2>
      <img src={image} alt={name}></img>
    </div>
}

function App() {
  return (
    <div>
      <h1>hello</h1>
      {foodILike.map(dish => {
        return <Food key={dish.id} name={dish.name} image={dish.image} />
      })} 
    </div>

  );
}

export default App;

댓글