ReactJS

React - props

jjangsh 2024. 8. 21. 20:03

01. Props의 개요

 

(1) props란 무엇일까요?

 

(1)-1. 컴포넌트끼리의 정보교환 방식

 

부모 컴포넌트가 자식 컴포넌트에게 물려준 데이터예요! 다시 말해, 컴포넌트 간의 정보 교류 방법입니다.

  1. props는 반드시 위에서 아래 방향으로 흐른다. 즉, [부모] → [자식] 방향으로만 흐른다(단방향).
  2. props는 반드시 읽기 전용으로 취급하며, 변경하지 않는다.

 

(2) props로 값 전달하기

 

(2)-1. 전달하기(주체 : 부모)

 

우리는 컴포넌트 간의 정보를 교류할 때 Props를 사용합니다. 다른 컴포넌트는 생략하고 Mother만 봅시다. 만약 Mother 컴포넌트가 가지고 있는 정보(값)를 Child에게 주고 싶을 때는 아래 코드와 같이 합니다.

motherName이라는 이름으로 name 값을 Child 컴포넌트에게 전달해 준 것입니다. 

// src/App.jsx

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;

 

(2)-2. 받기(주체 : 자식)

그러면, Mother가 전달해준 motherNameChild가 컴포넌트의 인자에서 props의 값을 받을 수 있습니다.

function Child(props){
	console.log(props)
	return <div>연결 성공</div>
}

 

  • 아래 사진처럼 Mother가 보내준 정보가 객체 형태로 보입니다
  • props란 결국 부모 컴포넌트가 자식에게 넘겨준 데이터들의 묶음이라고 볼 수 있습니다.
  • 이렇게 리액트에서는 Props를 통해 부모 컴포넌트로부터 자식 컴포넌트에 데이터를 넘겨줄 수 있습니다.

 

 

(3) props로 받은 값을 화면에 렌더링 하기

import React from "react";

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;

 

propsobject literal 형태이기 때문에 {props.motherName} 로 꺼내서 사용할 수 있습니다. object literalkeymotherName 인 이유는 우리가 Child로 보내줄 때 motherName={name} 으로 보내주었기 때문입니다.

 

(4) prop drilling

 

[부모] → [자식] → [그 자식] → [그 자식의 자식] 이 데이터를 받기 위해선 무려 3번이나 데이터를 내려줘야 해요. 이걸 바로 prop drilling, props가 아래로 뚫고 내려간다라고 라고 합니다.

 

우리는 이와 같은 패턴을 피해야 하기 때문에 'Redux'와 같은 데이터 상태관리 툴을 사용하게 됩니다.

export default function App() {
  return (
    <div className="App">
      <FirstComponent content="Who needs me?" />
    </div>
  );
}

function FirstComponent({ content }) {
  return (
    <div>
      <h3>I am the first component</h3>;
      <SecondComponent content={content} />|
    </div>
  );
}

function SecondComponent({ content }) {
  return (
    <div>
      <h3>I am the second component</h3>;
      <ThirdComponent content={content} />
    </div>
  );
}

function ThirdComponent({ content }) {
  return (
    <div>
      <h3>I am the third component</h3>;
      <ComponentNeedingProps content={content} />
    </div>
  );
}

function ComponentNeedingProps({ content }) {
  return <h3>{content}</h3>;
}

 

 

02. Props Children

 

(1) children이란?

 

(1)-1. 컴포넌트에서 말하는 children은 무엇을 의미할까요?

 

자식 컴포넌트로 정보를 전달하는 또 다른 방법이에요.

// src/App.jsx

import React from "react";

function User() {
  return <div></div>;
}

function App() {
  return <User>안녕하세요</User>;
}
export default App;

 

그런데 위 예시에서는 <User> 안녕하세요 </User> 이렇게 정보를 보내고 있습니다. <User hello='안녕하세요'> 이렇게 props를 보내던 방식과는 조금 다릅니다. 이것이 children props를 보내는 방식입니다. 그렇다면 자식 컴포넌트에서는 어떻게 정보를 받을까요? 정보를 받는 방식은 기존과 동일합니다. 대신 그 이름이 children으로 정해져 있습니다.

 

(2) children 값 받아서 렌더링 하기

 

User 컴포넌트에서 props.children을 받아 그대로 렌더링 해준 모습입니다.

import React from "react";

function User(props) {
  return <div>{props.children}</div>;
}

function App() {
  return <User>안녕하세요</User>;
}
export default App;

 

(3) children의 용도

 

(3)-1. Layout 컴포넌트를 만들 때 주로 사용

 

Layout 컴포넌트 안에는 header라는 컴포넌트가 있고, header 아래에 {props.children} 를 통해서 props를 받아 렌더링 하고 있습니다. 즉, Layout 컴포넌트가 쓰이는 모든 곳에서 <Layout>…</Layout> 안에 있는 정보를 받아서 가져올 수 있는 것이죠.

// src/About.jsx

import React from "react";
import Layout from "./components/Layout";

function App() {
  return (
    <Layout> 
      <div>여긴 App의 컨텐츠가 들어갑니다.</div>
    </Layout>
  );
}
export default App;

 

이 코드를 통해, Layout에 있는 header가 보여지게 되고, “여긴 App의 컨텐츠가 들어갑니다.” 라는 문장이 Layoutprops로 전달되는 것입니다. 결과적으로 우리는 header 컴포넌트를 Layout 컴포넌트에서 한 번만 작성하면 여러 페이지에서 모두 보여지게 할 수 있는 것입니다.

 

 

 

 

03. Props 추출

 

(1) 구조분해할당과 props

 

우리는 지금까지 자식 컴포넌트에서 props를 받을 때 이렇게 했습니다.

function Todo(props){
	return <div>{props.todo}</div>
}

 

문제는 없지만 todo 라는 props를 사용하는 모든 곳에서 props. 를 붙여줘야만 했죠. 이것을 조금 더 짧게 쓰는 방법이 있습니다. 바로 자바스크립트의 구조 분해 할당을 이용하는 것입니다. 앞서 설명했듯이 props는 object literal 형태의 데이터입니다. 그래서 우리는 구조 분해 할당을 이용할 수 있습니다

function Todo({ title }){
	return <div>{title}</div>
}

훨씬 간단하고 짧아졌습니다. 만약 여러 개의 props를 받는다면, { } 안에 여러개의 props를 그대로 써주면 됩니다.

function Todo({ title, body, isDone, id }){
	return <div>{title}</div>
}

 

(2) default arguments

 

(2)-1. default arguments란 무엇일까요?

 

부모 컴포넌트에서 자식 컴포넌트로 정보를 전달할 때 사용합니다. 때때로, 특정 props가 부모 컴포넌트로부터 전달되지 않을 수도 있는데, 이 경우 자식 컴포넌트에서 해당 props의 기본값을 설정해 줄 필요가 있습니다. 이를 위해 리액트에서는 "default arguments" 방식을 활용할 수 있습니다.

 

Default Arguments는 함수의 매개변수에서 기본값을 설정하는 자바스크립트의 표준 기능입니다. 리액트의 함수형 컴포넌트에서는 이 기능을 활용하여 props의 기본값을 쉽게 정의할 수 있습니다. 컴포넌트가 부모로부터 특정 props를 받지 못했을 경우에도 에러 없이 기본값을 사용하여 컴포넌트를 렌더링 할 수 있게 해 줍니다.

 

예를 들어, 어떤 컴포넌트가 사용자의 이름을 출력하는 기능을 가지고 있지만, 부모 컴포넌트가 이름을 제공하지 않는 경우가 있다고 가정해 보겠습니다.

 

function Welcome({ name = "Guest" }) {
    return <h1>Welcome, {name}!</h1>;
}

 

위 코드에서 name = "Guest"name prop이 전달되지 않았을 때 "Guest"라는 기본값을 사용하도록 설정합니다. 이렇게 설정함으로써, 부모 컴포넌트에서 name prop을 제공하지 않아도 Welcome 컴포넌트는 "Welcome, Guest!"라는 문구를 표시할 수 있습니다.