생각기록

2023-01-07 props 본문

강의 정리/React JS

2023-01-07 props

끼록관 2023. 1. 7. 18:05

컴포넌트로 코드를 줄이자

템플릿 기능!

 Props

원하는 정보를 컴포넌트에게 전달하는

이벤트, 객체, 배열, 문자 다 전달 가능

리액트에서는 props(properties) 라는 것으로 데이터 전달이 손쉽게 가능합니다

 

 

부모 컴퍼넌트가 자식 컴퍼넌트를 부를때,

즉, 데이터 전달 할때 props라는 객체형태로 전달

객체 내부에 객체, 함수 배열 변수 등등 다 전달이 가능하단 소리!

 

 

간단한 MainHeader 라는 컴포넌트 만들기

  • 매개변수 전달 부분에 { } 추가
  • 부모로 부터 받아올 props 명을 적는다.
import React from 'react'

// props 인자 받은것을 그대로 출력하는 형태
// 부모가 자식 컴포넌트에게 보내는 구조 메인헤더를 App.js..에서 
export default function MainHeader({ text }) {
  return (
    <h1>{text}</h1>
  )
}
import './App.css';
import List from './components/List';
import MainHeader from './components/MainHeader';

function App() {
  return (
    <div className="App">
      <List />
      {/* 구조 분해 할당으로 text라는 것을 받겟다 */}
      <MainHeader text="Hello, props world!"/>
    </div>
  );
}

export default App;

부모 App.js 에서 text="값"을 전달하고 있음

자식 MainHeader.jsx 이 { text }로  값을 받고 있다

 

 

 

다양한 데이터 받아오기

  • props는 다양한 데이터를 한번에 받아 올 수 있다
  • 그리고 다양한 데이터는 props라는 객체 하나로 받아서 사용이 가능함

 

원하는 값을 props로 전달

같은 컴포넌트를 썼지만!

props 값에 따라 출력결과물은 다르다

 

css 적용 방법

App.js 에 import

해당 컴포넌트 return div에 className="ListChild"라고 해야 한다.

 

 

구조분해 할당

인자로 받느냐 > 통으로 받느냐?

변수로 받느냐 차이

 

 

인자 

 

 

변수

 

 

클래스

클래스는 ! * this.props 

 

어쨋거나 클래스보다는 함수형이 컴퓨터적으로 메모리 덜 먹는다만 알아두면 된다

 


실습1 컴포넌트와 props 활용하기

해당 코드를 컴포넌트와 props를 사용해서 수정

<h2> <p> <hr>태그로 구성된 오늘 할 일 목록을 ListChild라는 컴포넌트로 만들기

내용은 props로 전달하여 오른쪽 코드의 결과물과 같은 결과물이 나올 수 있도록 만들기

 

풀이

더보기

ListChild 컴포넌트

//ListChild.jsx

import React from 'react'

export default function ListChild(props) {
  
  const { h2text, ptext } = props; 

  return (
    <div className='ListChild'>
      <h2>{h2text}</h2>
      <p>{ptext}</p>
      <hr />
    </div>
  )
}

List 파일

// List.jsx

import React from 'react'
import ListChild from './ListChild'

export default function List() {
  return (
    <div>
      <h1>오늘 해야할 일</h1>
      <hr />
      <ListChild h2text="리액트 공부하기" ptext="state 사용법 익히기"/>
      <ListChild h2text="코테 문제 풀기" ptext="Lv 0 정복 가즈아"/>
    </div>
  )
}

App.js파일

import './App.css';
import List from './components/List';


function App() {
  return (
    <div className="App">
      <List />      
    </div>
  );
}

export default App;

 

 

 

props 값을 컴포넌트에서 보내기

1. app.js 파일에서  컴포넌트에게 props를 보내보자

import './App.css';
import List from './components/List';

function App() {
  return (
    <div className="App">
      <List title="리액트 공부하기" content="스테이트 공부하기" />    
    </div>
  );
}

export default App;

2. 받는 법

import React from 'react'
import ListChild from './ListChild'

export default function List({ title, content }) {

  return (
    <div>
      <h1>오늘 해야할 일</h1>
      <hr />
      <ListChild h2text={title} ptext={content}/>
    </div>
  )
}

보낸 정보를 객체 형태로 { title, content } 인자로 보낸다.

그 값을 다른 컴포넌트 ListChild 컴포넌트에게 보낼 수 있다.

 

 

 

 

 

리액트 배열 데이터

더 간단하게 하는 방법은 jsx를 통해 html과 js를 혼용합시다.

 

MAP 함수

  • 동작 : 배열 값에 일일이 다 접근 한다. 개내한테 특정 일 해주고 리턴 시킴
  • return 을 하지 않으면, 값이 안그려진다!

 

리턴 > 0번째 값 읽고

다음 순회 > 1번째 값 

..

.

그리는 일을 함

// @ts-check

const arr = [1,2,3,4,5];
console.log(arr);

const resultArr = arr.map((el, index) => el * 3 );

  // 모든 배열 
  // console.log(el);
  // 몇번째 index인지
  // console.log(index);  

console.log(resultArr);

resultArr = arr 배열 * 3  값

 

import React from 'react'
import ListChild from './ListChild'
// import Modal from './Modal'

export default function List() {

  const dateArrr = [
    { 
   title: "리액트 공부하기",
    content: "state 활용법 익히기"},
    {
      title: "코테 문제 풀기",
      content: "Lv0 정복 가즈아"
    }
  ]
  return (

    <div>
      <h1>오늘 해야할 일</h1>
      <hr />

      {dateArrr.map((el) => {
        // map 함수로 첫번째, 두번째 값들이 배열 나열됨 
        return <ListChild h2text={el.title} ptext={el.content} />
      })}
      
    </div>
  )
}
import React from 'react'

export default function ListChild(props) {
  
  const { h2text, ptext } = props; 

  return (
    <div className='ListChild'>
      <h2>{h2text}</h2>
      <p>{ptext}</p>
      <hr />
    </div>
  )
}

위아래 동일!

 

 

근데 왜 오류가?

적어도 같은 부모를 공유하는 요소는 key 값을 유니크하게 지정해줘야 합니다.

리액트가 map으로 그려진 앨리먼트 중 어떤것을 컨트롤( 변경, 추가, 삭제 등)을 할지 구분하기 위해서 필요

 

mysql 같은 경우 프라이머리키를 지정해줍시다.

index 배열 주소는 고유하기때문에 

key ={index} > 이것은 최후의 방법

하지만 숫자라서 중복될 가능성이 높아서 유니크한 키값을 찾아주는게 좋다.

 

새로고침하면 오류가 사라진다.

 

map을 쓰면

귀찮게 하나하나 배열의 데이터 넣어줄 필요 없다

배열 데이터가 변경이 되어도 자연스럽게 적용

당연히 컴포넌트에만 적용할 필요도 없습니다

Map 의 리턴 값으로 원하는 것을 넣어줘도 됩니다!

map의 리턴요소는 하나의 부모요소만 가진다.

 


실습2. 배열을 map으로 그리기

왼쪽과 같은 데이터를 map을 이용해 다음과 같은 화면으로 출력

컴포넌트 props 사용 / html 코드를 리턴 둘 다 만들어 주세요

"컴포넌트 props 사용 / html 코드를 리턴 둘 다 만들어 주세요"

 

1. 컴포넌트 props 사용

자식 컴포넌트에게 정보를 보낸다.

 

2. html 코드 리턴

html코드 포함 리턴

import React from 'react'
import Ex2Child from './Ex2Child'

export default function Ex2() {
  const items = [
    {
      item: "PS5",
      price: "685,000원",
    },
    {
      item: "에어 프라이어",
      price: "50,000원",
    },
    {
      item: "사세 치킨윙",
      price: "11,500원",
    }
  ]

  return (
    
    <div>

      {/* 자식요소에게 props 데이터를 보낸다. */}
      {items.map((el, index) => {
        return <Ex2Child item={el.item} price={el.price} key={index} />
      })}

      {/* html에 직접 데이터 삽입 코드 리턴 */}
      {items.map((el, index) => {
        return (
          <div key={index}>
            <h2>품목명 : {el.item}</h2>
            <p>가격 : {el.price}</p>
          </div>
        )
      })}

    </div>
  )
}
import React from 'react'

export default function Ex2Child({ item, price }) {

  return (
    <div>
      <h2>품목명 : {item}</h2>
      <p>가격 : {price}</p>
      <hr />
    </div>
  )
}

근데 키값이 유니크하지 않다.. 둘다 같은 키다.

나중에 반드시 피해야 한다 기억!

 


props 활용하기

 

배열을 전달하고 props로 받아서 처리

props로는 배열 같은 다양한 자료형도 전달이 가능하다

배열을 받아서 처리하는 CustomList.jsx 컴포넌트를 만든다.

 

CustomList는 자식 컴포넌트

부모인 App이 props 객체로 데이터 전달

<CustomList arr={nameArr} /> 

import React from 'react'

export default function CustomList(props) {
  return (
    <ul>
      {props.arr.map((el) => 
        <li key={el}>
          {el}
        </li>
      )}
    </ul>
  )
}

App.js에서 임의의 배열을 만들어 전달

이런식으로 자식에게 부모가 데이터를 보낸다.

 

객체를 전달하고, props 로 받아서 처리

자식파일 CustomObj

부모파일 App 임의의 객체 정보 전달

obj = { 정보 }

 

 

안전하게 사용하기

백앤드에서 안전하게 사용하기 위함

• 만약 props 로 배열 또는 객체 데이터가 안들어 온다면 어떻게 될까요?

전달해주는 데이터가 없네요..?

• 이럴 때를 대비는 해주는 게 좋습니다

 

처리 방법

? 값이 있으면 실행하도록 하는 프로토타입 체이닝

에러발생이 안되는거지 제대로 굴러간다는 의미는 아니지만,

key의 값이 없어서 언디파인드인 상태입니다.

이럴땐 arr값이 언디파인드여서 에러가 뜨는거기 때문에

=> arr?이런식으로 처리해줍니다.

 

props.arr?.map(

프롭스의 arr의 값이 있으면 map 실행

없으면 실행하지 않는다 > 오류 없앰

import React from 'react'

export default function CustomList(props) {

  return (
    <ul>
      {/* arr?은 값이 있으면 map 실행 / 없으면 실행 x */}
      {props.arr?.map((el) => 
        <li key={el}>
          {el}
        </li>
      )}
    </ul>
  )
}

값이 들어올지 확신이 들지 않을 때 사용합시다.

남발하면, 결과적으로 원하던 결과랑 전혀다른 결과물이 나옵니다.

더 안전한 방법 if 문

if 문을 사용해서 props 확인 후 처리

단, jsx 문법 내부 (return 내부)에서는 사용 불가 > 3항 연산자 ? 사용

 

부모요소에서 객체로 데이터 전달하지 않음. 

<CustomObj  />

자식요소에서는  if문으로 props.obj 데이터 값이 있으면

 { name, age, nickName } = 데이터 값 ;

 

값이 없으면?

데이터가 없습니다 출력

 

자식요소

import React from 'react'

export default function CustomObj(props) {
  if(props.obj){
    const { name, age, nickName } = props.obj;
  
  // 리턴 내부의 jsx에는 if, for문 사용 금지 대신 삼항연산자, map같은것을 사용합니다.
  return (
      <div>
        <h1>이름 : {name}</h1>
        <h2>나이 : {age}</h2>
        <h2>별명 : {nickName}</h2>
      </div>
  )
} else {
  return(
    <div>데이터가 없습니다.</div>
  )
}
}

부모요소

import React from 'react'
import CustomObj from './CustomObj'

// 객체선언, 객체를 props로 전달
export default function CallCustomObj() {
  const pororoObj = {
    name: "뽀로로",
    age: "5살",
    nickName: "사고뭉치"
  }
  return (
    <div>
      {/* <CustomObj obj={pororoObj} /> */}
      <CustomObj />
    </div>
  )
}

 

요약

1. 배열 > 프로토타입 체이닝 단계에서  ? 사용

2. 제대로 처리하는 법 > 해당데이터 들어왓는지  if문으로 체크한다음 리턴에서 있으면 출력, 아니면 예외처리

 

 


실습3. props와 state 활용하기

프로필 변경하기 버튼 > props로 전달 된 오브젝트 배열 데이터들이 순서대로 바뀌도록 한다.

데이터 순환 구조하는 ChangeObj.js 컴포넌트를 만든다.

전달되는 오브젝트의 배열은 다음 장 코드를 참고

함수형으로 구현

구조분해 할당...

props로 데이터 주고 받는다.

부모에서 arr = { 객체 데이터 }

보냈으면,

 

자식에서는 props.arr로 받을 수 있다.

 

const [ index, setIndex ] = useState(0);

// 즉 index = 0; 

const obj = props.arr[index] ;

// props.arr[0] 첫번째 데이터 

 

함수

function changeProfile() {

// 데이터 갯수 3개-1 =  arr[2]까지 true

// arr[3] 부터는 err가 뜸 > err가 뜨지 않게 값을 0으로 초기화 

if( index === props.arr.length  -1 ) {

    setIndex (0);

} else {

    setIndex (index + 1);

}}

 

else는 정상적으로 다음 번호로 넘어가도록 하는 것

else문에서 index값이 2까지 가면,  다음 순회 if문에서 값을 0으로 초기화

다시 버튼을 누르면, else문을 타서 index + 1 하게 된다.

'강의 정리 > React JS' 카테고리의 다른 글

2023-01-12 React useRef  (0) 2023.01.12
2023-01-10  (0) 2023.01.10
2023-01-05 React state  (0) 2023.01.05
2023-01-05 React prettier, eslint 설치 사용추천  (0) 2023.01.05
2023-01-03 JSX 문법  (0) 2023.01.03