TIL | 컴포넌트 분리, props 데이터를 자식 컴포넌트로 보내기

0l0l·2021년 9월 21일
0

TIL

목록 보기
74/86

Mission!

자바스크립트 map() 함수를 통한 리액트 반복문 익히기

🔽 map() 함수를 사용하지 않고 작성한 코드

// App.js
import React from 'react';

function App() {
  const movies = [
    { title: 'movei01', year: 2001 },
    { title: 'movei02', year: 2002 },
    { title: 'movei03', year: 2003 },
    { title: 'movei04', year: 2004 },
  ];

  return (
    <div className="App">
      <h1>Movie List</h1>
      <div className="movie">
    	<div className="movieTitle">{movies[0].title}</div>
    	<div className="movieYear">{movies[0].year}</div>
      </div>
      <div className="movie">
    	<div className="movieTitle">{movies[1].title}</div>
    	<div className="movieYear">{movies[1].year}</div>
      </div>
<div className="movie">
    	<div className="movieTitle">{movies[2].title}</div>
    	<div className="movieYear">{movies[2].year}</div>
      </div>
    </div>
  );
}

export default App;

🔽 map() 함수를 사용해 반복문으로 작성한 코드

// App.js
import React from 'react';

function App() {
  const movies = [
    { title: 'movie01', year: 2001 },
    { title: 'movie02', year: 2002 },
    { title: 'movie03', year: 2003 },
    { title: 'movie04', year: 2004 },
  ];

  const renderMovies = movies.map(movie => { // 받아올 data에 대한 변수명 설정
    return ( // JSX 형식으로 리턴
      <div className="movie" key={movie.title}>
        <div className="movieTitle">{movie.title}</div>
        <div className="movieYear">{movie.year}</div>
      </div>
    );
  });
  
  return (
    <div className="App">
      <h1>Movie List</h1>
      {renderMovies}
    </div>
  );
}

export default App;

주의! map()을 사용할 때 꼭 해줘야 할 부분!
※ Warning: Each child in a list should have a unique "key" prop.

DB에서 데이터를 받아올 때 각각의 아이템을 구분할 수 있도록 고유한 속성을 key prop으로 설정하며, 보통 id로 설정합니다.
해당 key는 이후에 추가 및 삭제된 아이템을 리액트가 식별할 때 사용됩니다.

<div className="movie" key={movie.title}></div>
<div className="movie" key={movie.id}></div>

Mission!

위에 작성한 코드를 Movie 컴포넌트로 분리하기

  • map() 함수를 사용하지 않기 때문에 'key={movie.title}' 삭제
  • props 안에 movie를 넣기
    props를 받아와서 props 안에 movie(라는 data)를 받아온다
// components > Movie.js
import React from 'react';

const Movie = (props) => { // 함수형 컴포넌트 생성
  return ( // JSX 형태로 리턴
    <div className="movie">
      <div className="movieTitle">{props.movie.title}</div>
      <div className"movieYear">{props.movie.year}</div>
    </div>
  );
};

export default Movie; // Movie 컴포넌트 내보내기

데이터들을 props를 통해 Movie 컴포넌트로 보내서 Movie 컴포넌트에서 사용하기

// App.js
import React from 'react';
import Movie from './components/Movie'; // Movie 컴포넌트 받아오기

function App() {
  const movies = [
    { title: 'movie01', year: 2001 },
    { title: 'movie02', year: 2002 },
    { title: 'movie03', year: 2003 },
    { title: 'movie04', year: 2004 },
  ];

  const renderMovies = movies.map(movie => {
    return (
      <Movie movie={movie} key={movie.title} /> // Movie.js로 movie(데이터) 보내기
    );
  });

  return (
    <div className=movies>
      <h1>Movie List</h1>
      {renderMovies}
    </div>
  )
};

export default App;

※ Movie.js 에서 에러 발생!
TypeError: Cannot read property 'title' of undefined

App.js에서 Movie.js로 movie를 보내주지 않은 상태로 Movie.js에서 'props.movie.title'로 사용하고 있기 때문에 에러가 발생된 것입니다.
movie가 없는 상태로는 title과 year를 사용할 수 없습니다.

movie라는 props(첫번째 movie)에 movie라는 데이터(중괄호 안에 movie)를 넣어서 보내주면 됩니다.
movie가 Movie.js로 내려가면 movie라는 Object 형태의 데이터 안에 title과 year가 있어 에러가 발생하지 않고 사용할 수 있게 됩니다.

<Movie movie={movie} />

부모 컴포넌트에서 받아오는 데이터를 Movie.js에서 보여주기

  • movie(props)라는 이름으로 데이터 받아오기
  • props 반복하여 작성하지 않도록 구조분해할당
    Object를 받아오기 때문에 props 객체 안에 사용하는 부분(movie)만 작성
// components > Movie.js
import React from 'react';

const Movie = ({ movie }) => { // 구조분해할당
  return (
    <div className="movie">
      <div className="movieTitle">{movie.title}</div>
      <div className"movieYear">{movie.year}</div>
    </div>
  );
};

export default Movie; // Movie 컴포넌트 내보내기

*참고 영상: 컴포넌트와 props 데이터 보내기

profile
천방지축 빙글빙글

0개의 댓글