부모 컴포넌트로부터 받아온 데이터
// src/App.js
import React from "react";
function App() {
return <GrandFather />;
}
function GrandFather() {
return <Mother />;
}
function Mother() {
const name = '홍부인';
return <Child />; // Mother
}
function Child() {
return <div>연결 성공</div>;
}
export default App;
우리는 컴포넌트 간의 정보를 교류할 때 Props를 사용합니다. 다른 컴포넌트는 생략하고 Mother만 봅시다. 만약 Mother 컴포넌트가 가지고 있는 정보(값)를 Child에게 주고 싶을 때는 아래 코드와 같이 합니다.
motherName이라는 이름으로 name 값을 Child 컴포넌트에게 전달해준 것입니다. 우리는 이 과정을 “Props 로 정보를 전달했다” 라고 표현합니다.
// src/App.js
import React from "react";
function App() {
return <GrandFather />;
}
function GrandFather() {
return <Mother />;
}
function Mother() {
const name = '홍부인';
return <Child motherName={name} />; // 💡"props로 name을 전달했다."
}
function Child() {
return <div>연결 성공</div>;
}
export default App;
그러면, Mother가 전달해준 motherName은 Child가 어떻게 받을 수 있을까요? 이렇게 받습니다. 우리가 지금까지 한번도 관심있게 들여다보지 않았던 컴포넌트의 인자에서 props의 값을 받을 수 있습니다. 한번 콘솔에 찍어볼까요?
function Child(props){ //매개변수로 props 적어주기
console.log(props) //콘솔로 확인해보기
return <div>연결 성공</div>
}
아래 사진처럼 Mother가 보내준 정보가 객체 형태로 보이게 된다.
props란 결국 부모 컴포넌트가 자식에게 넘겨준 데이터들의 묶음이다.

import React from "react";
// div안에서 { } 를 쓰고 props.motherName을 넣어보세요.
function Child(props) {
return <div>{props.motherName}</div>;
}
function Mother() {
const name = "홍부인";
return <Child motherName={name} />;
}
function GrandFather() {
return <Mother />;
}
function App() {
return <GrandFather />;
}
export default App;

값이 화면에 찍히게 된다.
props는 object literal 형태이기 때문에 {props.motherName} 로 꺼내서 사용할 수 있다. object literal의 key가 motherName 인 이유는 우리가 Child로 보내줄 때 motherName={name} 으로 보내주었기 때문.
❓ object literal 란 {key: “value”} 데이터 형태를 의미합니다. 더 자세한 설명
JSX에서는 HTML만 쓸 수 있는 줄 알았는데, 자바스크립트 코드를 사용했죠? 맞습니다. JSX에서도 { } 중괄호를 사용하면 자바스크립트 코드를 사용할 수 있습니다.
자식 컴포넌트에서는 부모 컴포넌트로 props를 전달할 수 없음. 오직 부모 컴포넌트에서 자식 컴포넌트로만 props를 전달할 수 있다.
GrandFather 컴포넌트에서 GrandFatherName을 만들어서 화면에 렌더링 해봅시다.src 폴더 안에 App.js 에 있는 내용을 모두 지우고 새롭게 작성해봅니다.// src/App.js
import React from "react";
function App() {
return <GrandFather />;
}
function GrandFather() {
const name = "할아버지"; //GrandFather 컴포넌트에 이름 설정
return <Mother grandFatherName={name} />;
// Mother 컴포넌트에 grandFatherName이란 키에 name값 주기
}
//GrandFather 컴포넌트에서 props 받아오기
function Mother(props) {
return <Child grandFatherName={props.grandFatherName} />;
}
//Child 컴포넌트에 grandFatherName 이라는 이름으로 props의 grandFatherName 값 주기
//Mother 컴포넌트에서 props 받기
function Child(props) {
return <div>{props.grandFatherName}</div>;
}
// props의 grandFatherName 값 출력하기
export default App;
아니다!
function Child(aaa) {
return <div>{aaa.grandFatherName}</div>;
}
이렇게 파라미터 값을 바꿔줘도 잘 동작함

function Child(props) {
const { grandfatherName } = props;
//props 데이터를 구조분해할당해줌
console.log(grandfatherName); //할아버지 라고 찍힘
return <div>{grandfatherName}</div>; //그대로 할아버지라고 찍힘
}

<Component props={props} />
와 다른 방식으로 자식 컴포넌트에 정보를 전달해주어도 사용 할 수 있는 props가 있습니다. 바로 children 입니다.
// src/App.js
import React from "react";
function User() {
return <div></div>;
}
function App() {
return <User>안녕하세요</User>;
}
export default App;
App.js에 App 컴포넌트와 User 컴포넌트가 있습니다. 그리고 App 컴포넌트가 User 컴포넌트를 자식으로 품고 있습니다. 그리고 User 컴포넌트 사이에 ‘안녕하세요' 라는 문장이 있습니다. 근데 yarn start 를 해서 화면을 보면 아무것도 화면에 표시되지 않습니다.
왜 그럴까요? 그 이유는 App 컴포넌트에서 ‘안녕하세요' 라는 정보를 보냈지만, User 컴포넌트에서는 그 정보를 받지 않았기 때문입니다.
우리는 부모 컴포넌트에서 정보를 보냈을 때, 자식 컴포넌트에서 그 정보를 사용하고 싶다면 props를 통해 정보를 받아와야 했습니다. 하지만 위 예시에서는 User 컴포넌트에서 그 정보를 받고 있지 않기 때문에 화면에 어떠한 문장도 보이지 않고 있는 것 입니다.
그런데 위 예시에서는 <User>안녕하세요</User> 이렇게 정보를 보내고 있습니다. <User hello='안녕하세요'> 이렇게 props를 보내던 방식과는 조금 다릅니다. 이것이 children props를 보내는 방식입니다. 그렇다면 자식 컴포넌트에서는 어떻게 정보를 받을까요? 정보를 받는 방식은 기존과 동일합니다. 대신 그 이름이 children 으로 정해져 있습니다. 아래 코드를 입력해보세요. 콘솔에 ‘안녕하세요'가 잘 보이시나요?
function User(props) {
console.log(props.children)
return <div></div>;
}
자, 그럼 위에서의 코드를 수정해보겠습니다. User 컴포넌트에서 props.children을 받아 그대로 렌더링 해준 모습입니다. 이제 화면에 정상적으로 ‘안녕하세요’ 라는 문장이 보입니다!
import React from "react";
function User(props) {
return <div>{props.children}</div>;
}
function App() {
return <User>안녕하세요</User>;
}
export default App;
<User>안녕하세요</User> 자식을 불러오는 태그 사이에 들어간 데이터는 다 children 이라는 키의 값이 된다.

Layout 컴포넌트 안에는 header 라는 컴포넌트가 있고, header 아래에 {props.children} 를 통해서 props를 받아 렌더링 하고 있습니다. 즉, Layout 컴포넌트가 쓰여지는 모든 곳에서 … 안에 있는 정보를 받아서 가져올 수 있는 것이죠.
// src/About.js
import React from "react";
import Layout from "./components/Layout";
function App() {
return (
<Layout>
<div>여긴 App의 컨텐츠가 들어갑니다.</div>
</Layout>
);
}
export default App;
이 코드를 통해, Layout에 있는 header가 보여지게 되고, “여긴 App의 컨텐츠가 들어갑니다.” 라는 문장이 Layout의 props로 전달되는 것 입니다. 결과적으로 우리는 header 컴포넌트를 Layout 컴포넌트에서 한번만 작성하면 여러 페이지에서 모두 보여지게 할 수 있는 것 입니다.

Layout 컴포넌트를 About 컴포넌트에 또 사용했습니다. 어떤가요? children이 이해가 되시나요!?
// src/About.js
import React from "react";
import Layout from "./components/Layout";
function About() {
return (
<Layout>
<div>여긴 About의 컨텐츠가 들어갑니다.</div>
</Layout>
);
}
export default About;

우리는 지금까지 자식 컴포넌트에서 props를 받을 때 이렇게 했습니다.
function Todo(props){
return <div>{props.todo}</div>
}
문제는 없지만 todo 라는 props를 사용하는 모든 곳에서 props. 를 붙여줘야만 했죠. 이것을 조금 더 짧게 쓰는 방법이 있습니다. 바로 자바스크립트의 구조 분해 할당을 이용하는 것 입니다. 앞서 설명했듯이 props는 object literal 형태의 데이터 입니다. 그래서 우리는 구조 분해 할당을 이용할 수 있습니다. 이렇게 말이죠.
function Todo({ title }){
return <div>{title}</div>
}
여러개의 Props를 받는다면?
function Todo({ title, body, isDone, id }){
return <div>{title}</div>
}
defaultProps란, 부모 컴포넌트에서 props를 보내주지 않아도 설정될 초기 값 입니다.
컴포넌트를 만들고 자식 컴포넌트에서 props를 받다보면, 자주 받거나 또는 무조건 받아야 하는 props들이 있습니다. 예를 들어 나이를 props로 받아 화면에 렌더링 하는 컴포넌트가 있다고 예를 들어보죠.
// components/Child.js
import React from 'react';
function Child({ name }){
return <div>내 이름은 {name} 입니다. </div>
}
export default Child
Child 컴포넌트 입장에서는 부모 컴포넌트에서 name을 props 정보를 받기 전까지는 name 이 없는 상태죠. 그래서 자식 컴포넌트 입장에서는 name이 무엇인지 알 수 없습니다. 결과적으로 자식컴포넌트는 화면에 아무것도 표시해주지 못하게 됩니다. (이렇게요 내 이름은 "" 입니다. )
굉장히 어색하겠죠? 그래서 부모 컴포넌트에서 props를 받기전까지 임시로 사용 할 수 있는 props를 설정 할 수 있습니다. Child 컴포넌트에서 직접이요! 이후에 부모 컴포넌트에서 name props가 오게되면 설정된 defaultProps는 사라지고 내려 받은 props로 값이 바뀌게 됩니다.
// components/Child.js
import React from 'react';
function Child({ name }){
return <div>내 이름은 {name} 입니다. </div>
}
// 이렇게 설정합니다.
Child.defaultProps={
name: '기본 이름'
}
export default Child
이렇게 defaultProps를 설정하면, 부모 컴포넌트로부터 아직 props 값을 받지 못했더라고 임시로 props의 값을 채울 수 있습니다. 그리고 부모 컴포넌트로부터 props가 오게되면 defaultProps 값은 진짜 props 값으로 변경됩니다. 아래 코드처럼도 할 수 있는데, 방법만 다를 뿐 모두 defaultProps를 설정하는 방법 입니다. 마치 함수의 default argument를 설정하는 것과 같죠?
import React from 'react';
// 구조 분해 할당 문법을 사용하면 이렇게도 할 수 있어요.
function Child({ name = '기본이름' }){
return <div>내 이름은 {name} 입니다. </div>
}
export default Child
object literal 이란 무엇인가?
default argument란 무엇인가?