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}
/>
);
}
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
에 렌더링을 위해 person
과 size
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들을 어떻게 사용하는지 생각할 필요없이 Profile
의 person
또는 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로 구조분해 합니다.
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이 없이 렌더링된다면, size
는 100
으로 설정됩니다.
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를 사용합니다.
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
컴포넌트는 부모 컴포넌트로부터 color
와 time
이라는 두 가지 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 andundefined
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 asCard
component’schildren
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> ); }