본문 바로가기
REACT

[React] 272샘의 React9 ( Props 구조 분해 )

by 미눅스[멘토] 2024. 10. 10.
728x90

 

 

 

https://deahan.tistory.com/428

 

[React] 272샘의 React8 ( Props 이해 사용 )

https://deahan.tistory.com/427 [React] 272샘의 React7 (블락 기호 {} 사용)https://deahan.tistory.com/426 [React] 272샘의 React6 (JSX)https://deahan.tistory.com/425 [React] 272샘의 React5 (개발 폴더 파일 구조)https://deahan.tistory.com

deahan.tistory.com

를 읽고 뭐야  쉽네 라고 생각했다면 미안하당 그건 아니다 라고 철희샘이 그랬음...

 

Container.jsx 를 아래 처럼 배열 map 메소드를 이용 리팩토링 해보자

 
import "./Container.css";
import Friend from "./Friend";
function Container() {
  // 데이터가 이렇게 있다고 가정, 나중엔 서버에서 가져와야함.
  const mFriends = [
    { mid: "likeminux", name: "🍴미누", age: 32, nickName: "무용잘함" },
    { mid: "samssoju", name: "✨경민", age: 29, nickName: "흥 폭발" },
    { mid: "rocket", name: "😊카리나", age: 24, nickName: "로켓펀치" },
    { mid: "dancingman", name: "👀선주", age: 29, nickName: "이모티콘쩐주" },
    { mid: "e7e", name: "💜E7E", age: 19, nickName: "아무말막잔치" },
    { mid: "alcol", name: "🖤병철", age: 29, nickName: "주사시로" },
    { mid: "lucky", name: "💟원영", age: 29, nickName: "럭키비키" },
    { mid: "ariel", name: "🍑조이", age: 29, nickName: "인어공주" },
  ];

  return (
    <div className="container">
      <h1>e7e 베.푸(Very Proud)들</h1>
      {/* 배열 map 메소드를 이용 뺑뺑이 */}
      {mFriends.length &&
        mFriends.map((friend) => (
          <Friend
            key={friend.mid}
            mid={friend.mid}
            name={friend.name}
            age={friend.age}
            nickName={friend.nickName}
          />
        ))}
      <div className="minux">&copy;MINUX 만만세</div>
    </div>
  );
}

export default Container;
 

그저 일관성 있게 데이터 모음을 배열로 밖으로 빼고, 문법에 맞게 

map으로 뺑뺑이 돌린 것 뿐이라서, 결과는 아래처럼 예상됨

여기서 주의를 해야 하는 것이 있는데,  반복 돌릴 때 JSX에 key 속성을 주지 않으면

missing(없어) 되어 missing(그리)이라고  빨간 웨이브 라인이 아주 머라 한당.

key속성을 넣어주기만 하면 빨간 웨이브 라인은 떠나지만...  알아야 한다.

 key값을 아무렇게나 주면 오동작이 발생할 수 있다는 사실을....

그저 뺑뺑도는 index값을 주는 건 성의도 없을 뿐 더러, Risk가 크다.

React는 내부적으로 key속성을 이용하여 해당 객체의 상태를 관리하기 때문인데,

 

예를 들면  미누의 id가 minu공, 경민의 id는 simsim 인뎅,

갑자기  경민의 id를 minu라 하면 어찌 헷깔리지 아니 할 수 있는가!

그저 DB의 Primary-Key처럼 일관성 있게 key값을 유지하려는 맘이 있으면 다 해결된다

 

Friend.jsx  를 아래 처럼 수정해 보장. (매개 변수에 빨간 줄이 생길 수 있는데 생겨도 일단 무시)

 
import "./Friend.css";

function Friend({ mid, name, age, nickName}) {
  console.log("check:",mid, name,age,nickName)
  return (
    <div className="friend">
      <img
        alt="아바타"
      />
      <h5>{name}</h5>
      <h5>{age}</h5>
      <h5>{nickName}</h5>
    </div>
  );
}

export default Friend;
 

Friend Function의 매개변수에 구조 분해를 적용했당.(구조 분해?)

실행결과는 앞과 동일하지만, 소스에 아래 그림과 같은 빨간 줄에 맘이 불편...

에러는 아니고, 단지 eslint 메세지일 뿐이닝 호들갑은 여기선 사치일 뿐

그럼 eslint이 뭔지 알려면 lint가 무엇인지를 알아야 한다

 

Lint는 개발에서  문법 엉터리, 규칙 맘대로, 버그 예상등 코딩에 빠진 당신을 옆에서 도와주는 Tool이다.

[ 플러그인 설치한 게 기억났다면 난 당신을 사랑할 뿐이다.]

현실에 비유하면 당신의 코딩에 이래라 저래라 훈수두는 꼰대 쌤!, 또는 훌륭한  비서 일지도....

es는 자바스크립트를 EcmaScript 라고도 부르는뎅, 버젼을 말할 때 ES6등이 기억날것이다.

결국 eslint 자바스크립트 코드 작성시에 코드에 문제가 보이면 그걸 미리 알려주는 tool이다

 

빨간줄이 맘을 흔드니 먼저 크게 2가지 방법으로 해결해 보자

첫번째 방법: 귀차니즘이 있는 날이거나, 후다닥 넘어가고 싶을땐 이게 좋다.

마우스로 Quick Fix 부분을 누르공, 아래 그림처럼 나오면 그냥 위에껄 선택한다.

 

스프링을 배웠다면 @SuppressWarings 어노테이션 같은 경고 무시 의미다.

Friend 함수 위에  아래와 같은 주석이 들어가고, 맘에서 가시가 떠난다.

 
// eslint-disable-next-line react/prop-types
function Friend({ mid, name, age, nickName }) {
    /* 코드 생략 */
}
 

 

두번째 방법: eslint가 Props 타입을 제대로 체크할 수 있도록 체크 기준을 줘야 한다

Terminal에 아래 명령어로 prop-types 모듈을 설치.( reactcomponent폴더에서)

[ 어쩌면 안해도 된다. 웬지 이미 들어있는 느낌인데, 노파심에서 하자 ]

npm install prop-types  //  npm install prop-types -D 해도 된다

 

Friend.jsx  를 아래 처럼 다시 수정해 보자.

 
import "./Friend.css";
import PropTypes from "prop-types";

Friend.propTypes = {
  mid: PropTypes.string.isRequired,
  name: PropTypes.string.isRequired,
  age: PropTypes.number.isRequired,
  nickName: PropTypes.string.isRequired,
};

function Friend({ mid, name, age, nickName}) {
  console.log("check:",mid, name,age,nickName)
  return (
    <div className="friend">
      <img
        alt="아바타"
      />
      <h5>{name}</h5>
      <h5>{age}</h5>
      <h5>{nickName}</h5>
    </div>
  );
}

export default Friend;

영어 글자 자체에 울렁증이 없다면

의미가 읽으면서 뇌에서 동시 번역이 이루어질것이다.(자주 보면 결국 친해짐!)

간단히 번역해 보면, Props 타입에는 mid, name,age,nickName 속성이 있고,

age는 숫자여야 하고, 나머지는 모두 문자열인데, 모두 꼭 필요하단 의미이고,

eslint는 이 기준으로 매개변수를 체크하게 됨.

[  과제: 과연 정말로 저 모든게 체크될까? 자바스크립트는 선언시 타입을 정하지 않는데! ]

 

경고 메세지는 해결했지만, 근본적인 문제가 남아있다. 구조분해?

2023.06.14 - [자바스크립트] - 시베리안 허숙희의 자바스크립트 비기닝 18 (구조 분해 등등..)

글을 읽는다면 철희샘이 당신의 손바닥을 긁어 주겠다고함. (분명 의외롱 시원할 것이다...)

 

구조분해할당( Destructuring Assignment)을 이해하면

매개변수 처리부분이 그냥 바로 JUST  뭐야 이런 간단한 규칙이야? 하게 된다.

 

 

index.html이 위치한 곳에 아래 내용으로 파일을 만들자

구조분해.html

 
<!DOCTYPE html>
<meta charset="UTF-8" />
<script>
  // 구조 분해 이해해보자, [] 와 {} 2가지로
  // 리액트뿐만 아니라 프론트 프레임워크(vue, angular등)에 상습적으로 사용됨
  // 머릿속에 일단 1개 기억해요 = 양쪽이 같은 형태([]냐? {}냐?)
  // 먼저 배열 구조 분해
  const minuxArr = ["유진", "나현", "다희", "선영", "미숙"];
  const [, , dh, sy] = minuxArr;
  alert(`check dh sy ${dh} ${sy}`); // "check dh sy 다희 선영"

  const [yj, ...others] = minuxArr;
  alert(`check yj ${yj}`); // "check yj 유진"
  alert(`check others ${others}`); // "check others 나현,다희,선영,미숙"
  alert("부디 느낌이 왔길... 순서가 보였으면!");

  // 객체 {}, 사실 배열도 객체인데, 이해를 위해 의도적 분리
  const e7eObj = { name: "민진", age: 24, nickName: "귀요미" };
  const { nickName, name } = e7eObj;
  alert(`check name ${name}`);
  alert(`check nickName ${nickName}`);
  alert("부디 느낌이 왔길... 속성명이 변수명으로!");

  // 함수 매개변수 보통의 처리 방식
  function fCK(pObj) {
    alert(`${pObj.name}${pObj.alias}`);
  }
  fCK({ name: "지원", alias: "수학천재" });

  // 함수 매개변수에 구조 분해 적용
  function fCK2({ alias, name }) {
    alert(`${name}${alias}`);
  }
  fCK2({ name: "미선", alias: "달린댜" });
</script>
 

http://localhost:5173/구조분해.html

로 실행하여 결과와 소스를 매칭 시키는 시간을 가져여만 한다. 

 

 구조분해가 먼지?, 함수의 매개변수를 구조분해하는 내용만 넣었으니,

차분히 받아들이도록 하장. [ES6 이상에 들어간 그저 새로운 문법,기능이다]

쉽지만 소스 뉘앙스는 좀 더 많은 걸 담고 있다.

[] 은 new Array() 의 의미
{}은 new Object() 의 의미 

머릿속에 위의 내용을 담고, 다시 한번 구조분해를 바라보기 바란다.

 

억지 응용 한번 더 해 보자.(이건 전투력 증강을 위해 그냥 해보는 거다.)

Container.jsx 를 아래 처럼 수정하자.

 
import "./Container.css";
import Friend from "./Friend";
function Container() {
  // 데이터가 이렇게 있다고 가정, 나중엔 서버에서 가져와야함.
  const mFriends = [
    { mid: "likeminux", name: "🍴미누", age: 32, nickName: "무용잘함" },
    { mid: "samssoju", name: "✨경민", age: 29, nickName: "흥 폭발" },
    { mid: "rocket", name: "😊카리나", age: 24, nickName: "로켓펀치" },
    { mid: "dancingman", name: "👀선주", age: 29, nickName: "이모티콘쩐주" },
    { mid: "e7e", name: "💜E7E", age: 19, nickName: "아무말막잔치" },
    { mid: "alcol", name: "🖤병철", age: 29, nickName: "주사시로" },
    { mid: "lucky", name: "💟원영", age: 29, nickName: "럭키비키" },
    { mid: "ariel", name: "🍑조이", age: 29, nickName: "인어공주" },
  ];

  return (
    <div className="container">
      <h1>e7e 베.푸(Very Proud)들</h1>
      {/* 배열 map 메소드를 이용 뺑뺑이 */}
      {mFriends.length &&
        mFriends.map((friend) => <Friend key={friend.mid} friend = {friend} /> )}
      <div className="minux">&copy;MINUX 만만세</div>
    </div>
  );
}

export default Container;
 

 

아래 내용이 바뀐 부분이다. 객체를 속성1개에 통째로 넘겼다.

<Friend key={friend.mid} friend={friend} />

 

받는 부분도 바뀌어야 하니...

Friend.jsx도 아래 처럼 수정!!

 
import "./Friend.css";
import PropTypes from "prop-types";

Friend.propTypes = {
    friend: PropTypes.any.isRequired,
};

function Friend({ friend}) {
  console.log("check:",friend)
  return (
    <div className="friend">
      <img
        src={`https://api.dicebear.com/9.x/adventurer/svg?seed=${friend.mid}`}
        alt="아바타"
      />
      <h5>{friend.name}</h5>
      <h5>{friend.age}</h5>
      <h5>{friend.nickName}</h5>
    </div>
  );
}

export default Friend;

아래 의미는 Friend 함수의 매개변수(Props)에는 friend속성이 있어야 하는데,

속성의 값은 뭐가 오든 상관없다(any)는 의미다!!

Friend.propTypes = {  friend: PropTypes.any.isRequired,};

 

실행해 보면 같은 결과가 보일 것이다.

 

출처 : https://e-7-e.tistory.com/257