[새싹 프론트엔드] Props Array Component

Ryu·2022년 11월 25일
1

새싹

목록 보기
20/36

프로퍼티

프로퍼티(properties)란?

영화 목록을 컴포넌트로 표현한다고 가정

  1. Movie 컴포넌트 생성 후 영화 정보 입력

  1. App.js 컴포넌트에서 Movie 컴포넌트 3번 사용

해결 방법

  • Movie 컴포넌트는 1개만 사용
  • App.js에서 Movie 컴포넌트에 필요한 데이터를 전달

프로퍼티란?

  • 상위 컴포넌트에서 하위 컴포넌트로 전달되는 읽기 전용 데이터
    • 단방향 데이터 흐름
    • 부모가 자식한테만 데이터를 보낼 수 있음
  • 프로퍼티 값은 수정이 불가능함
  • properties를 줄여서 props라고도 함
  • 전달 방법

프로퍼티 값 자료형

  • App.js 기준으로 코딩
  • 문자열
    • 큰따옴표(””) 사용

      <MyComponent name = "정수아" />
  • 문자열 이외의 값
    • 숫자, 불리언, 배열, 객체, 함수 등

    • 중괄호 사용

      <MyComponent age = {20} />

프로퍼티 값 전달 및 조회

props를 통해 하나의 값 전달하기

  • 데이터 조회하기
    • FirstProps.js

      import React from 'react';
      
      	function FirstProps(props){
      		return (
      			<div>
      				안녕하세요. 제 이름은 {props.name}입니다.
      			</div>
      		);
      	}
      
      export default FirstProps;
  • 데이터 전달하기
    • App.js

      import React from 'react';
      import FirstProps from './FirstProps';
      
      function App(){
      	return (
      		<div>
      			<FirstProps name="정수아" />
      		</div>
      	);
      }
      
      export default App;

props를 통해 여러 개의 값 전달하기

  • 데이터 조회하기
    • FirstProps.js

      function FirstProps(props){
      	return (
      		<div>
      			<h1>
      				안녕하세요. 제 이름은 {props.name}입니다. 
      				<br/>
      				제가 좋아하는 색은 {props.color}입니다.
      			</h1>
      		</div>
      	);
      }
  • 데이터 전달하기
    • App.js

      import React from 'react';
      import FirstProps from './FirstProps';
      
      function App(){
      	return (
      		<div>
      			<FirstProps name="정수아" color="blue"/>
      		</div>
      	);
      }
      
      export default App;

props 값 간결하게 조회하기

  • 비구조화 할당(=구조 분해) 문법 사용
function FirstProps({name, color}){
	return (
		<div>
			<h1>
				안녕하세요. 제 이름은 {name}입니다.
				<br/>
				제가 좋아하는 색은 {color}입니다.
			</h1>
		</div>
	);
}
function FirstProps(props){
	const {name, color} = props;

		return (
			<div>
				<h1>
					안녕하세요. 제 이름은 {name}입니다.
					<br/>
					제가 좋아하는 색은 {color}입니다.
				</h1>
			</div>
		);
}

클래스형 컴포넌트에서 props 사용

  • 데이터 전달하기
    • App.js

      import React, { Component } from 'react';
      import ClassProps from './ClassProps';
      
      class App extends Component {
      	render() {
      		return (
      			<div>
      				<ClassProps name="정수아" color="blue"/>
      			</div>
      		);
      	}
      }
      
      export default App;
  • 데이터 조회하기
    • ClassProps.js

      import React, { Component } from 'react';
      
      class ClassProps extends Component {
      	// render: 안에 있는 내용 출력
      	render() {
      		const {name, color} = this.props;
      		return (
      			<div>
      				<h1>
      					안녕하세요. 제 이름은 {name}입니다.
      					<br/>
      					제가 좋아하는 색은 {color}입니다.
      				</h1>
      			</div>
      		);
      	}
      }
      
      export default ClassProps;

불리언 프로퍼티

불리언 프로퍼티 사용하기

  • 불리언 값은 특별한 방법으로 전달 가능
    • true는 프로퍼티의 이름만 선언함

      <BooleanComponent boolValue />
      // true 생략 가능
    • false는 프로퍼티의 이름을 생략함

      <BooleanComponent />
  • BooleanComponent.js
import React from 'react';

function BooleanComponent({bored}){
	const message = bored ? '놀러 가자' : '하던 일 열심히 마무리하기'

	return (
		<div>
			{message} 
		</div>
	);
}

export default BooleanComponent;
  • App.js
import React from 'react';
import BooleanComponent from './BooleanComponent';

function App(){
	return (
		<div>
			<div>
				<b>지루할 때 : </b>
				<BooleanComponent bored/>
			</div>
			<div>
				<b>즐거울 때 : </b>
				<BooleanComponent/>
			</div>
		</div>
	);
}

export default App;

defaultProps

defaultProps

  • props를 지정하지 않았을 때 기본적으로 사용할 값을 설정
  • DefaultProps.js
import React from 'react’;

function DefaultProps({name}){
	return(
		<div>
			안녕하세요. 제 이름은 {name}입니다.
		</div>
	);
}

// 컴포넌트이름.defaultProps
DefaultProps.defaultProps = {
	name : "이름없음"
}

export default DefaultProps;
  • App.js
import React from 'react';
import DefaultProps from './DefaultProps';

function App(){
	return (
		<div>
			<DefaultProps name="정수아"/>
			<DefaultProps/>
		</div>
	);
}

export default App;

props.children

props.children

  • 컴포넌트 태그 사이에 넣은 값을 조회할 때 사용
<ParentComponent>
	안녕하세요
	<childComponent/>
</ParentComponent>
  • Wrapper.js
import React from 'react';

function Wrapper(){
	const style = {
		border : '3px solid red',
		padding : '20px'
	}
	
	return (
		<div style={style}>
		</div>
	);
}

export default Wrapper;
  • App.js
import React from 'react';
import Wrapper from './Wrapper';
import HeaderComponent from './CreateHeader';
import BodyComponent from './CreateBody';
import FooterComponent from './CreateFooter';

function App(){
	return (
		<Wrapper>
			<HeaderComponent/>
			<BodyComponent/>
			<FooterComponent/>
		</Wrapper>
	);
}

export default App;
  • 실행 결과
    • Wrapper 컴포넌트만 화면에 출력
    • HeaderComponent, BodyComponent, FooterComponent는 화면에 출력 안됨
  • Wrapper.js 수정
import React from 'react';

function Wrapper({children}){
	const style = {
		border : '3px solid red',
		padding : '20px'
	}
	
	return (
		<div style={style}>
			{children}
		</div>
	);
}

export default Wrapper;

propTypes

propTypes

  • 특정 컴포넌트에 꼭 전달되어야 하는 프로퍼티를 필수 프로퍼티로 지정하거나 프로퍼티의 타입을 지정할 때 사용
  • 사용 방법
    • prop-types를 import 해야 함

      import PropTypes from 'prop-types';

propTypes - 타입 지정

  • PropTypesComponent.js
import React from 'react';
import PropTypes from 'prop-types';

function PropTypesComponent({name}){
	return(
		<div>
			안녕하세요. 제 이름은 {name}입니다.
		</div>
	);
}

PropTypesComponent.propTypes = {
	name : PropTypes.string
}

export default PropTypesComponent;
  • App.js
import React from 'react';
import PropTypesComponent from './PropTypesComponent';

function App(){
	return (
		<PropTypesComponent name={3}/>
	);
}

export default App;

propTypes - 필수 프로퍼티 지정

  • PropTypesComponent.js 수정
import React from 'react';
import PropTypes from 'prop-types';

function PropTypesComponent({name, favoriteNumber}){
	return(
		<div>
		안녕하세요. 제 이름은 {name}입니다.<br/>
		제가 좋아하는 숫자는 {favoriteNumber}입니다.
		</div>
	);
}

PropTypesComponent.propTypes = {
	name : PropTypes.string,
	favoriteNumber : PropTypes.number.isRequired
}

export default PropTypesComponent;
  • App.js
import React from 'react';
import PropTypesComponent from './PropTypesComponent';

function App(){
	return (
		<PropTypesComponent name=“정수아”/>
	);
}

export default App;
  • App.js
import React from 'react';
import PropTypesComponent from './PropTypesComponent';

function App(){
	return (
		<PropTypesComponent name=“정수아” favoriteNumber={7}/>
	);
}

export default App;

배열 컴포넌트

영화 목록 앱 구현

예) 영화 목록 앱 구현

  • MovieComponents.js
import React from 'react';

function MovieComponent(props){
    const { title, open } = props;
    return (
			<div>
				<h1>제목 : {title} </h1> 
				<h1>개봉 : {open} </h1> 
				<hr/>
			</div> 
			);
};

export default MovieComponent;

App.js

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

function App(){
	return (
		<div>
			<MovieComponent title="공조2:인터내셔날" open="2022.09.07"/> 
			<MovieComponent title="인생은 아름다워" open="2022.09.28"/> 
			<MovieComponent title="정직한 후보2" open="2022.09.28"/>
		</div> 
	);
}

export default App;

문제점

  1. 만약 출력해야 할 영화 정보가 1,000개라면?
    • 1,000개를 반복해서 코드 작성
    • 각 태그마다 서로 다른 데이터 값 입력
  2. 서버에서 데이터를 받아오는 경우
    • 몇 개의 데이터가 넘어오는지 알 수 없음

map() 함수

map() 함수란?

  • 배열 안의 모든 요소들의 값을 변경해서 새로운 배열을 생성하는 함수
const arr = [1, 2, 3, 4, 5];
const modifiedArr = arr.map(function(element){
    return element * 3;
});

console.log(modifiedArr);

map() 함수 동작 과정

map() 함수를 이용하여 영화 목록 앱 수정

map() 함수를 이용하여 영화 목록 앱 수정하기

  • 데이터는 서버에서 전달받는다고 가정
  • 데이터는 객체 형식으로 배열에 저장
function App(){
	const movieList = [
		{
			title : "공조2: 인터내셔날", 
			open : "2022.09.07",
		},
		{
			title : "인생은 아름다워", 
			open : "2022.09.28",
		},
		{
			title : "정직한 후보2", 
			open : "2022.09.28",
		}
	];
   return (<></>);
}
export default App;
  • App.js
const movieList = [ ...생략... ]

return ( 
	<>
		{
			movieList.map(movie =>
			<MovieComponent title={movie.title} open={movie.open} />)
		}
	</> 
);

영화 포스터 추가하기

  • 이미지 데이터 추가
const movieList = [
	{
		title : "공조2: 인터내셔날",
		open : "2022.09.07",
		img : "https://search.pstatic.net/common?type=o&size~~~"
	}, 
];
  • img 프로퍼티 추가
return <MovieComponent title={movie.title} open={movie.open} img={movie.img} />
  • MovieComponent 수정
function MovieComponent(props){
	const { title, open, img } = props;

	return (
		<div>
			<h3>제목 : {title} </h3> 
			<h3>개봉 : {open} </h3> 
			<img src = {img} /> 
			<hr/>
		</div> 
	);
};

배열 컴포넌트

배열 컴포넌트를 위한 map() 함수 사용 방법

  • 자바스크립트의 배열
    • 다양한 자료형을 저장 가능

      // 숫자형
      const numberList = [1, 2, 3, 4, 5];
      
      // 2개 이상의 자료형
      const mixedList = [1, ‘str’, {}, function a() { }];
    • XML과 JSX 또한 저장 가능

      // JSX 배열
      const componentList = [ <MyComponent />, <MySecondComponent /><b>Hi</b> ];
  • map() 함수를 이용하여 배열의 데이터를 JSX로 변환
    • App.js

      function App(){
      	const todoList = [
      		{ taskName : '빨래하기', finished : false }, 
      		{ taskName : '공부하기', finished : true },
      	];
      
      	return ( 
      		<>
      			{
      				todoList.map(todo => <div>{ todo.taskName }</div>)
      			} 
      		</>
      	); 
      }
    • JSX 배열 리턴

      [<div>빨래하기</div>, <div>공부하기</div>]
  • 배열 데이터를 컴포넌트의 프로퍼티에 전달하기
    • App.js

      function App(){
      	const todoList = [
      		{ taskName : '빨래하기', finished : false },
      		{ taskName : '공부하기', finished : true }, 
      	];
      	
      	return (
      		<>
      			{
      				todoList.map(todo =>
      						<TodoTask taskName={todo.taskName}/>)
      			}
      		</>
      	); 
      }
    • TodoTask.js

      import React from 'react';
      
      function TodoTask(props){
      		const { taskName } = props;
      
          return (
              <div>
                  {taskName}
              </div>
      		); 
      };
      
      export default TodoTask;
    • 실행 결과

      [<TodoTask taskName=“빨래하기”/>, <TodoTask taskName=“공부하기” />]

key props

배열 컴포넌트의 key props

  • 개발자 도구를 보면 다음과 같은 경고 메시지가 나옴
    • 배열 속성에 key값이 없기 때문
    • 리액트의 원소가 리스트에 포함되면서 리액트 원소들의 유일성이 사라짐
    • 배열 속성에 key값을 추가하여 해결 가능함
  • 배열 컴포넌트에 key props 추가
    • 배열 컴포넌트는 배열 원소의 개수만큼 반복하므로 성능에 영향을 많이 줌
    • 배열에 key값을 추가하면 성능 향상에 도움이 됨
      • key값을 정의하여 출력한 배열 컴포넌트를 다시 출력해야 하는 경우, 리액트 엔진이 기존 컴포넌트를 재활용하여 성능을 높일 수 있음
    • key props는 리액트 내부에서 사용되는 특수한 props이기 때문에 하위 컴포넌트에는 전달되지 않음
  • 기존 코드 수정하기
    • App.js

      function App(){
      		const todoList = [
      				{ taskName : '빨래하기', finished : false },
      				{ taskName : '공부하기', finished : true } 
      		];
      		
      		return ( 
      				<>
      						{
      						todoList.map(todo =>
      						<div key={todo.taskName}>{todo.taskName}</div>)
      						} 
      				</>
      		); 
      }

새싹DT 기업연계형 프론트엔드 실무 프로젝트 과정 6주차 블로그 포스팅

0개의 댓글