비공식 사이트. 24.12.31. 폐쇄예정
공식사이트 바로가기

Passing Props to a Component컴포넌트에 props 전달하기

React components use props to communicate with each other. Every parent component can pass some information to its child components by giving them props. Props might remind you of HTML attributes, but you can pass any JavaScript value through them, including objects, arrays, and functions. React 컴포넌트는 props를 이용해 서로 통신합니다. 모든 부모 컴포넌트는 props를 줌으로써 몇몇의 정보를 자식 컴포넌트에게 전달할 수 있습니다. props는 HTML 속성(attribute)을 생각나게 할 수도 있지만, 객체, 배열, 함수를 포함한 모든 JavaScript 값을 전달할 수 있습니다.

You will learn학습 내용

  • How to pass props to a component
  • How to read props from a component
  • How to specify default values for props
  • How to pass some JSX to a component
  • How props change over time
  • 컴포넌트에 props를 전달하는 방법
  • 컴포넌트에서 props를 읽는 방법
  • props의 기본값을 지정하는 방법
  • 컴포넌트에 JSX를 전달하는 방법
  • 시간에 따라 props가 변하는 방식

Familiar props친숙한 props

Props are the information that you pass to a JSX tag. For example, className, src, alt, width, and height are some of the props you can pass to an <img>: props는 JSX 태그에 전달하는 정보입니다. 예를 들어, className, src, alt, width, height<img> 태그에 전달할 수 있습니다:

function Avatar() {
  return (
    <img
      className="avatar"
      src="https://i.imgur.com/1bX5QH6.jpg"
      alt="Lin Lanying"
      width={100}
      height={100}
    />
  );
}

export default function Profile() {
  return (
    <Avatar />
  );
}

The props you can pass to an <img> tag are predefined (ReactDOM conforms to the HTML standard). But you can pass any props to your own components, such as <Avatar>, to customize them. Here’s how! <img> 태그에 전달할 수 있는 props는 미리 정의되어 있습니다. (ReactDOM는 HTML 표준을 준수합니다.) 자신이 생성한 <Avatar>와 같은 어떤 컴포넌트든 props를 전달할 수 있습니다. 방법은 다음과 같습니다.

Passing props to a component컴포넌트에 props 전달하기

In this code, the Profile component isn’t passing any props to its child component, Avatar: 아래 코드에서 Profile 컴포넌트는 자식 컴포넌트인 Avatar에 어떠한 props도 전달하지 않습니다:

export default function Profile() {
return (
<Avatar />
);
}

You can give Avatar some props in two steps. 다음 두 단계에 걸쳐 Avatar에 props를 전달할 수 있습니다.

Step 1: Pass props to the child component자식 컴포넌트에 props 전달하기

First, pass some props to Avatar. For example, let’s pass two props: person (an object), and size (a number): 먼저, Avatar 에 몇몇 props를 전달합니다. 예를 들어, person (객체)와 size (숫자)를 전달해 보겠습니다:

export default function Profile() {
return (
<Avatar
person={{ name: 'Lin Lanying', imageId: '1bX5QH6' }}
size={100}
/>
);
}

Note

If double curly braces after person= confuse you, recall they’re merely an object inside the JSX curlies. 만약 person= 뒤에 있는 이중 괄호가 혼란스럽다면, JSX 중괄호 안의 객체라고 기억하시면 됩니다.

Now you can read these props inside the Avatar component. 이제 Avatar 컴포넌트 내 props를 읽을 수 있습니다.

Step 2: Read props inside the child component자식 컴포넌트 내부에서 props 읽기

You can read these props by listing their names person, size separated by the commas inside ({ and }) directly after function Avatar. This lets you use them inside the Avatar code, like you would with a variable. 이러한 props들은 function Avatar 바로 뒤에 있는 ({}) 안에 그들의 이름인 person, size 등을 쉼표로 구분함으로써 읽을 수 있습니다. 이렇게 하면 Avatar 코드 내에서 변수를 사용하는 것처럼 사용할 수 있습니다.

function Avatar({ person, size }) {
// person and size are available here
}

Add some logic to Avatar that uses the person and size props for rendering, and you’re done. Avatar에 렌더링을 위해 personsize props를 사용하는 로직을 추가하면 끝입니다.

Now you can configure Avatar to render in many different ways with different props. Try tweaking the values! 이제 Avatar를 다른 props를 이용해 다양한 방식으로 렌더링하도록 구성할 수 있습니다. 값을 조정해보세요!

import { getImageUrl } from './utils.js';

function Avatar({ person, size }) {
  return (
    <img
      className="avatar"
      src={getImageUrl(person)}
      alt={person.name}
      width={size}
      height={size}
    />
  );
}

export default function Profile() {
  return (
    <div>
      <Avatar
        size={100}
        person={{ 
          name: 'Katsuko Saruhashi', 
          imageId: 'YfeOqp2'
        }}
      />
      <Avatar
        size={80}
        person={{
          name: 'Aklilu Lemma', 
          imageId: 'OKS67lh'
        }}
      />
      <Avatar
        size={50}
        person={{ 
          name: 'Lin Lanying',
          imageId: '1bX5QH6'
        }}
      />
    </div>
  );
}

Props let you think about parent and child components independently. For example, you can change the person or the size props inside Profile without having to think about how Avatar uses them. Similarly, you can change how the Avatar uses these props, without looking at the Profile. props를 사용하면 부모 컴포넌트와 자식 컴포넌트를 독립적으로 생각할 수 있습니다. 예를 들어, Avatar 가 props들을 어떻게 사용하는지 생각할 필요없이 Profileperson 또는 size props를 수정할 수 있습니다. 마찬가지로 Profile을 보지 않고도 Avatar가 props를 사용하는 방식을 바꿀 수 있습니다.

You can think of props like “knobs” that you can adjust. They serve the same role as arguments serve for functions—in fact, props are the only argument to your component! React component functions accept a single argument, a props object: props는 조절할 수 있는 “손잡이(볼륨 다이얼같은 느낌)“라고 생각하면 됩니다. props는 함수의 인수와 동일한 역할을 합니다. 사실 props는 컴포넌트에 대한 유일한 인자입니다! React 컴포넌트 함수는 하나의 인자, 즉,props 객체를 받습니다:

function Avatar(props) {
let person = props.person;
let size = props.size;
// ...
}

Usually you don’t need the whole props object itself, so you destructure it into individual props. 보통은 전체 props 자체를 필요로 하지는 않기에, 개별 props로 구조분해 합니다.

Pitfall | 함정

Don’t miss the pair of { and } curlies inside of ( and ) when declaring props: props를 선언할 때 () 안에 {} 쌍을 놓치지 마세요:

function Avatar({ person, size }) {
// ...
}

This syntax is called “destructuring” and is equivalent to reading properties from a function parameter: 이 구문을 “구조 분해 할당”이라고 부르며 함수 매개 변수의 속성과 동등합니다.

function Avatar(props) {
let person = props.person;
let size = props.size;
// ...
}

Specifying a default value for a propprop의 기본값 지정하기

If you want to give a prop a default value to fall back on when no value is specified, you can do it with the destructuring by putting = and the default value right after the parameter: 값이 지정되지 않았을 때, prop에 기본값을 주길 원한다면, 변수 바로 뒤에 = 과 함께 기본값을 넣어 구조 분해 할당을 해줄 수 있습니다.

function Avatar({ person, size = 100 }) {
// ...
}

Now, if <Avatar person={...} /> is rendered with no size prop, the size will be set to 100. 이제, <Avatar person={...} />size prop이 없이 렌더링된다면, size100으로 설정됩니다.

The default value is only used if the size prop is missing or if you pass size={undefined}. But if you pass size={null} or size={0}, the default value will not be used. 기본값은 size prop이 없거나 size={undefined} 로 전달될 때 사용됩니다. 그러나 만약 size={null} 또는 size={0}으로 전달된다면, 기본값은 사용되지 않습니다.

Forwarding props with the JSX spread syntaxJSX 전개 구문으로 props 전달하기

Sometimes, passing props gets very repetitive: 때때로 전달되는 props들은 반복적입니다:

function Profile({ person, size, isSepia, thickBorder }) {
return (
<div className="card">
<Avatar
person={person}
size={size}
isSepia={isSepia}
thickBorder={thickBorder}
/>
</div>
);
}

There’s nothing wrong with repetitive code—it can be more legible. But at times you may value conciseness. Some components forward all of their props to their children, like how this Profile does with Avatar. Because they don’t use any of their props directly, it can make sense to use a more concise “spread” syntax: 반복적인 코드는 가독성을 높일 수 있다는 점에서 잘못된 것은 아닙니다. 하지만 때로는 간결함이 중요할 때도 있습니다. Profile 컴포넌트가 Avatar 컴포넌트에게 그런 것처럼, 일부 컴포넌트는 그들의 모든 props를 자식 컴포넌트에 전달합니다. 이 경우 Profile 컴포넌트는 props를 직접적으로 사용하지 않기 때문에, 보다 간결한 “전개(spread)” 구문을 사용하는 것이 합리적일 수 있습니다:

function Profile(props) {
return (
<div className="card">
<Avatar {...props} />
</div>
);
}

This forwards all of Profile’s props to the Avatar without listing each of their names. 이렇게 하면 Profile의 모든 props를 각각의 이름을 나열하지 않고 Avatar로 전달합니다.

Use spread syntax with restraint. If you’re using it in every other component, something is wrong. Often, it indicates that you should split your components and pass children as JSX. More on that next! 전개 구문은 제한적으로 사용하세요. 다른 모든 컴포넌트에 이 구문을 사용한다면 문제가 있는 것입니다. 이는 종종 컴포넌트들을 분할하여 자식을 JSX로 전달해야 함을 나타냅니다. 더 자세히 알아봅시다!

Passing JSX as children자식을 JSX로 전달하기

It is common to nest built-in browser tags: 브라우저 빌트인 태그는 중첩하는 것이 일반적입니다:

<div>
<img />
</div>

Sometimes you’ll want to nest your own components the same way: 때로는 만든 컴포넌트들끼리 중첩하고 싶을 수도 있습니다:

<Card>
<Avatar />
</Card>

When you nest content inside a JSX tag, the parent component will receive that content in a prop called children. For example, the Card component below will receive a children prop set to <Avatar /> and render it in a wrapper div: JSX 태그 내에 콘텐츠를 중첩하면, 부모 컴포넌트는 해당 컨텐츠를 children이라는 prop으로 받을 것입니다. 예를 들어, 아래의 Card 컴포넌트는 <Avatar /> 로 설정된 children prop을 받아 이를 감싸는 div에 렌더링할 것입니다:

import Avatar from './Avatar.js';

function Card({ children }) {
  return (
    <div className="card">
      {children}
    </div>
  );
}

export default function Profile() {
  return (
    <Card>
      <Avatar
        size={100}
        person={{ 
          name: 'Katsuko Saruhashi',
          imageId: 'YfeOqp2'
        }}
      />
    </Card>
  );
}

Try replacing the <Avatar> inside <Card> with some text to see how the Card component can wrap any nested content. It doesn’t need to “know” what’s being rendered inside of it. You will see this flexible pattern in many places. <Card> 내부의 <Avatar>를 텍스트로 바꾸어 <Card> 컴포넌트가 중첩된 콘텐츠를 어떻게 감싸는지 확인해 보세요. <Card>는 children 내부에서 무엇이 렌더링되는지 “알아야 할” 필요가 없습니다. 이 유연한 패턴은 많은 곳에서 볼 수 있습니다.

You can think of a component with a children prop as having a “hole” that can be “filled in” by its parent components with arbitrary JSX. You will often use the children prop for visual wrappers: panels, grids, etc. children prop을 가지고 있는 컴포넌트는 부모 컴포넌트가 임의의 JSX로 “채울” 수 있는 “구멍”을 가진 것이라고 생각할 수 있습니다. 패널, 그리드 등의 시각적 래퍼에 종종 children prop를 사용합니다.

A puzzle-like Card tile with a slot for "children" pieces like text and Avatar

Illustrated by Rachel Lee Nabors

How props change over time시간에 따라 props가 변하는 방식

The Clock component below receives two props from its parent component: color and time. (The parent component’s code is omitted because it uses state, which we won’t dive into just yet.) 아래의 Clock 컴포넌트는 부모 컴포넌트로부터 colortime이라는 두 가지 props를 받습니다. (부모 컴포넌트의 코드는 아직 자세히 다루지 않을 state를 사용하기 때문에 생략합니다).

Try changing the color in the select box below: 아래 select box의 색상을 바꿔보세요:

export default function Clock({ color, time }) {
  return (
    <h1 style={{ color: color }}>
      {time}
    </h1>
  );
}

This example illustrates that a component may receive different props over time. Props are not always static! Here, the time prop changes every second, and the color prop changes when you select another color. Props reflect a component’s data at any point in time, rather than only in the beginning. 이 예시는 컴포넌트가 시간에 따라 다른 props를 받을 수 있음을 보여줍니다. Props는 항상 고정되어 있지 않습니다! 여기서 time prop은 매초마다 변경되고, color prop은 다른 색상을 선택하면 변경됩니다. Props는 컴포넌트의 데이터를 처음에만 반영하는 것이 아니라 모든 시점에 반영합니다.

However, props are immutable—a term from computer science meaning “unchangeable”. When a component needs to change its props (for example, in response to a user interaction or new data), it will have to “ask” its parent component to pass it different props—a new object! Its old props will then be cast aside, and eventually the JavaScript engine will reclaim the memory taken by them. 그러나 props는 불변으로, 컴퓨터 과학에서 “변경할 수 없다”는 뜻의 용어입니다. 컴포넌트가 props를 변경해야 하는 경우(예: 사용자의 상호작용이나 새로운 데이터에 대한 응답으로), 부모 컴포넌트에 다른 props, 즉,새로운 객체를 전달하도록 “요청”해야 합니다! 그러면 이전의 props는 버려지고(참조를 끊는다), 결국 JavaScript 엔진은 기존 props가 차지했던 메모리를 회수(가비지 컬렉팅. GC)하게 됩니다.

Don’t try to “change props”. When you need to respond to the user input (like changing the selected color), you will need to “set state”, which you can learn about in State: A Component’s Memory. “props 변경”을 시도하지 마세요. 선택한 색을 변경하는 등 사용자 입력에 반응해야 하는 경우에는 State: 컴포넌트의 메모리에서 배울 “set state”가 필요할 것입니다.

Recap요약

  • To pass props, add them to the JSX, just like you would with HTML attributes.
  • To read props, use the function Avatar({ person, size }) destructuring syntax.
  • You can specify a default value like size = 100, which is used for missing and undefined props.
  • You can forward all props with <Avatar {...props} /> JSX spread syntax, but don’t overuse it!
  • Nested JSX like <Card><Avatar /></Card> will appear as Card component’s children prop.
  • Props are read-only snapshots in time: every render receives a new version of props.
  • You can’t change props. When you need interactivity, you’ll need to set state.
  • Props를 전달하려면 HTML 속성 사용할 때와 마찬가지로 JSX에 props를 추가합니다.
  • Props를 읽으려면 function Avatar({ person, size }) 구조 분해 구문을 사용합니다.
  • size = 100 과 같은 기본값을 지정할 수 있으며, 이는 누락되거나 undefined 인 props에 사용됩니다.
  • 모든 props를 <Avatar {...props} /> JSX 전개 구문을 사용할 수 있지만, 과도하게 사용하지 마세요.
  • <Card><Avatar /></Card>와 같이 중첩된 JSX는 Card컴포넌트의 children prop로 표시됩니다.
  • Props는 읽기 전용 스냅샷으로, 렌더링할 때마다 새로운 버전의 props를 받습니다.
  • Props는 변경할 수 없습니다. 상호작용이 필요한 경우 state를 설정해야 합니다.

Challenge 1 of 3: Extract a component컴포넌트 추출하기

This Gallery component contains some very similar markup for two profiles. Extract a Profile component out of it to reduce the duplication. You’ll need to choose what props to pass to it. Gallery 컴포넌트에는 두가지 프로필에 대한 몇가지 비슷한 마크업이 포함되어 있습니다. 중복을 줄이기 위해 Profile 컴포넌트를 추출해 보세요. 어떤 props를 전달할지 골라야 할 수 있습니다.

import { getImageUrl } from './utils.js';

export default function Gallery() {
  return (
    <div>
      <h1>Notable Scientists</h1>
      <section className="profile">
        <h2>Maria Skłodowska-Curie</h2>
        <img
          className="avatar"
          src={getImageUrl('szV5sdG')}
          alt="Maria Skłodowska-Curie"
          width={70}
          height={70}
        />
        <ul>
          <li>
            <b>Profession: </b> 
            physicist and chemist
          </li>
          <li>
            <b>Awards: 4 </b> 
            (Nobel Prize in Physics, Nobel Prize in Chemistry, Davy Medal, Matteucci Medal)
          </li>
          <li>
            <b>Discovered: </b>
            polonium (chemical element)
          </li>
        </ul>
      </section>
      <section className="profile">
        <h2>Katsuko Saruhashi</h2>
        <img
          className="avatar"
          src={getImageUrl('YfeOqp2')}
          alt="Katsuko Saruhashi"
          width={70}
          height={70}
        />
        <ul>
          <li>
            <b>Profession: </b> 
            geochemist
          </li>
          <li>
            <b>Awards: 2 </b> 
            (Miyake Prize for geochemistry, Tanaka Prize)
          </li>
          <li>
            <b>Discovered: </b>
            a method for measuring carbon dioxide in seawater
          </li>
        </ul>
      </section>
    </div>
  );
}