언어 및 도구들 공부/React

컴포넌트와 props 03

Dr.Mlem 2024. 11. 20. 22:21

컴포넌트와 props 02에 이어서 마지막...

10-04의 grade_table의 index.js, GradeItem.js, 그리고 data의 GradeData.js가 어떤 연산과정을 이어서

화면에 결과가 출력되는지 정리를 마무리함.

Q1.

일단 알겠어. 그렇다면 다시 정리해볼게. 그렇다면 내가 이해한게 맞는지 확인해줘.

// GradeData.js

const GradeData = [
    { "이름": "철수", "학년": 1, "성별": "남자", "국어": 98, "영어": 78, "수학": 88, "과학": 64 },
    { "이름": "영희", "학년": 2, "성별": "여자", "국어": 88, "수학": 62, "과학": 72 },
    { "이름": "민수", "학년": 1, "성별": "남자", "국어": 92, "영어": 70, "수학": 76, "과학": 78 },
    { "이름": "수현", "학년": 3, "성별": "여자", "국어": 63, "영어": 60, "수학": 31 },
    { "이름": "호영", "학년": 4, "성별": "남자", "국어": 88, "영어": 50, "과학": 88 }
];

export default GradeData;

 

이 배열의 원소 중 하나는

{ "이름": "철수", "학년": 1, "성별": "남자", "국어": 98, "영어": 78, "수학": 88, "과학": 64 } 가 있어.

 

이게 일단 index.js에서,

 

{GradeData.map((v, i)=> {
                        return(
                            // 여기서 v는, GradeData 배열의 요소 하나. 
                            //{ "이름": "철수", "학년": 1, "성별": "남자", "국어": 98, "영어": 78, "수학": 88, "과학": 64 }
                            // 이 한 줄이 v가 되는것.
                            // 이 v들이 들어있는 배열을 이용해서, 태그 덩어리를 만드는 것.
                            <GradeItem key={i}
                            name={v.이름}
                            level={v.학년}
                            sex={v.성별}
                            kor={v.국어}
                            eng={v.영어}
                            math={v.수학}
                            sinc={v.과학}/>
                        );
                    })}

 

이 부분에서 i가 0일때, 첫번째 반복문을 돌게 되는데,

v.이름이라는 값에, Map함수 반복문에 들어온 첫 번째 Json 내의 "이름"="철수" 라는 키-값 쌍에 접근하여 값 "철수"를 전달받고,

그 값이 name에 저장되고, 그렇게 쭈우우욱 하나씩 하나씩 저장되어서 sinc 까지 저장된 후, GradeItem.js 함수형 컴포넌트로 전달되는데,

<GradeItem key={0} name="철수" level={1} sex="남자" kor={98} eng={78} math={88} sinc={64} />

 

이런 꼴로 전달되게 되는데,

import React from "react";

import PropTypes from "prop-types";

const GradeItem = ({name, level, sex, kor=0, eng=0, math=0, sinc=0}) => { // 원래는 이렇게 작성 안하고 아래에서 defaultProps로 줬는데, 
                                                                          //해당 내용을 지원 종료할거라는 리엑트놈...ㅠㅠ
    const sum = parseInt(kor+eng+math+sinc);
    const avg = parseInt(sum / 4);

    return (
        <tr align="center">
            <td><strong>{name}</strong></td>
            <td><strong>{level}</strong></td>
            <td>{sex}</td>
            <td>{kor}</td>
            <td>{eng}</td>
            <td>{math}</td>
            <td>{sinc}</td>
            <td><strong>{sum}</strong></td>
            <td><strong>{avg}</strong></td>
        </tr>
    );
};

 

 

저렇게 전달된 속성 값들은, 리엑트가 정해둔 규칙에 의해서, json 꼴로 입력되게 되어서, 그 값들이 props가 되고, 그 json이 구조 분해를 통해서 각각의 이름을 갖는 변수가 되어서,

 

{name, level, sex, kor=0, eng=0, math=0, sinc=0}

로 들어간 Json의 각각의 값들은, 각각 변수 name, level, sex, kor, eng, math, sinc 가 되는거고, GradeItem 함수형 컴포넌트는 그 변수들을 이용해서

return (
        <tr align="center">
            <td><strong>{name}</strong></td>
            <td><strong>{level}</strong></td>
            <td>{sex}</td>
            <td>{kor}</td>
            <td>{eng}</td>
            <td>{math}</td>
            <td>{sinc}</td>
            <td><strong>{sum}</strong></td>
            <td><strong>{avg}</strong></td>
        </tr>
    );

 

이 값을 리턴하고, 그렇게 index.js에서 i가 0일때 첫 번째 <tr>태그 묶음이 생기고, 그걸 반복하면서 테이블이 완성되는게 맞아?


 

A1.

네, 정확하게 이해하셨습니다! 🎉👏

당신이 설명한 과정을 다시 정리해보면 리액트의 컴포넌트와 props의 동작 방식을 아주 잘 이해하고 계신 것을 알 수 있습니다. 전체 흐름은 아래와 같이 요약할 수 있습니다.


1. 데이터 준비

  • GradeData 배열의 첫 번째 원소는:
{ "이름": "철수", "학년": 1, "성별": "남자", "국어": 98, "영어": 78, "수학": 88, "과학": 64 }

이 원소가 map 함수의 첫 번째 반복에서 v로 들어옵니다.


2. map 함수에서 데이터 처리

  • v.이름, v.학년, v.성별 등으로 v 객체의 속성에 접근하여 각 값을 꺼냅니다.
  • 이렇게 꺼낸 값을 <GradeItem>의 props로 전달합니다.

첫 번째 반복에서 실행되는 JSX는:

<GradeItem 
    key={0}
    name="철수"
    level={1}
    sex="남자"
    kor={98}
    eng={78}
    math={88}
    sinc={64}
/>

이 코드가 호출되며, GradeItem 컴포넌트로 아래와 같은 형태의 props 객체가 전달됩니다:

{
    name: "철수",
    level: 1,
    sex: "남자",
    kor: 98,
    eng: 78,
    math: 88,
    sinc: 64
}

3. GradeItem 컴포넌트에서 props 처리

GradeItem 함수형 컴포넌트는 props 객체를 구조 분해 할당하여 받습니다:

const GradeItem = ({ name, level, sex, kor=0, eng=0, math=0, sinc=0 }) => {
  • props.name → name으로 꺼내짐: "철수"
  • props.level → level으로 꺼내짐: 1
  • 나머지도 동일한 방식으로 꺼냄.

4. GradeItem 컴포넌트가 JSX를 반환

GradeItem은 받은 값을 이용해 <tr> 태그를 생성합니다:

<tr align="center">
    <td><strong>{name}</strong></td>   <!-- "철수" -->
    <td><strong>{level}</strong></td> <!-- 1 -->
    <td>{sex}</td>                    <!-- "남자" -->
    <td>{kor}</td>                    <!-- 98 -->
    <td>{eng}</td>                    <!-- 78 -->
    <td>{math}</td>                   <!-- 88 -->
    <td>{sinc}</td>                   <!-- 64 -->
    <td><strong>{sum}</strong></td>   <!-- 총점: 328 -->
    <td><strong>{avg}</strong></td>   <!-- 평균: 82 -->
</tr>
  • 총점(sum)과 평균(avg)은 컴포넌트 내부에서 계산합니다.
const sum = parseInt(kor + eng + math + sinc); // 328
const avg = parseInt(sum / 4);                 // 82

5. 테이블 행 추가

<GradeItem> 컴포넌트는 완성된 <tr> 태그를 반환하고, 이 값이 map 함수의 결과로 포함됩니다.

첫 번째 반복의 결과는:

<tr align="center">
    <td><strong>철수</strong></td>
    <td><strong>1</strong></td>
    <td>남자</td>
    <td>98</td>
    <td>78</td>
    <td>88</td>
    <td>64</td>
    <td><strong>328</strong></td>
    <td><strong>82</strong></td>
</tr>

6. 반복 실행

map 함수는 배열의 각 원소에 대해 동일한 과정을 반복하며 각 행(<tr>)을 생성합니다.


7. 최종 결과

모든 행이 <tbody> 안에 포함되어 테이블이 완성됩니다.


결론

당신의 설명은 리액트의 데이터 흐름과 동작 방식을 정확히 이해한 것입니다. 👏

  • props는 JSON 객체처럼 컴포넌트로 전달됩니다.
  • 컴포넌트 내부에서는 props를 구조 분해 할당으로 받아서 사용합니다.
  • GradeItem은 반복적으로 호출되어, <tr> 태그를 반환하며, 테이블이 완성됩니다.

 

 

어느정도는 흐름을 처음부터 끝까지 나의 것으로 받아들이기는 힘들 것 같다.

대략적인 흐름을 이해하는 선에서 마무리하는게 좋을 것 같다...

아주 처음부터 끝까지 뜯어보는 것은 이제 한계인 것 같네 ㅇㅅㅇ;;;