컴포넌트에 Props 전달
- Published on
- 이 글은 리액트 컴포넌트에서 props를 전달하고 활용하는 방법에 대한 설명을 포함하고 있습니다.
Table of Contents
리액트 컴포넌트는 서로 통신하기 위해 props를 사용합니다. 부모 컴포넌트는 자식 컴포넌트에 props를 제공하여 정보를 전달할 수 있습니다. Props는 HTML 속성을 생각나게 할 수도 있지만, 객체, 배열 및 함수와 같은 모든 JavaScript 값으로 props를 통해 전달할 수 있습니다.
익숙한 props
props는 JSX 태그에 전달하는 정보입니다. 예를 들어, className, src, alt, width, height는 <img>
에 전달할 수 있는 일부 props입니다.
<img>
태그에 전달할 수 있는 props는 미리 정의되어 있습니다 (리액트DOM은 HTML 표준을 준수합니다). 하지만 <Avatar>
와 같이 직접 만든 컴포넌트에도 다양한 props를 전달할 수 있습니다. 다음은 그 방법입니다!
컴포넌트에 props 전달하기
다음 코드에서 Profile 컴포넌트는 자식 컴포넌트인 Avatar에 어떤 props도 전달하지 않고 있습니다.
export default function Profile() {
return (
<Avatar />
);
}
Avatar에 일부 props를 전달할 수 있습니다.
단계 1: 자식 컴포넌트에 props 전달하기
먼저, Avatar에 일부 props를 전달하세요. 예를 들어, person (객체)
와 size (숫자)
라는 두 가지 props를 전달해 보겠습니다.
export default function Profile() {
return (
<Avatar
person={{ name: 'Lin Lanying', imageId: '1bX5QH6' }}
size={100}
/>
);
}
참고
person=
다음의 이중 중괄호가 혼란스럽다면, 그저 JSX 중괄호 내의 객체일 뿐임을 상기하세요.
이제 Avatar 컴포넌트 내에서 이러한 props를 읽을 수 있습니다.
단계 2: 자식 컴포넌트 내에서 props 읽기
person, size와 같은 이름을 콤마로 구분하여 ({
와 })
바로 다음의 function Avatar 뒤에 나열하여 이러한 props를 읽을 수 있습니다. 이를 통해 변수처럼 Avatar 코드 내에서 사용할 수 있습니다.
function Avatar({ person, size }) {
// person과 size를 이곳에서 사용할 수 있습니다
}
person과 size props를 사용하여 렌더링하는 데 필요한 로직을 Avatar에 추가하면 됩니다.
이제 다양한 props로 Avatar를 다양한 방식으로 렌더링할 수 있습니다. 값을 조정해 보세요!
Props를 사용하면 부모와 자식 컴포넌트를 독립적으로 생각할 수 있습니다. 예를 들어, Profile 내에서 person 또는 size props를 변경하더라도 Avatar가 이를 사용하는 방식을 생각할 필요가 없습니다. 마찬가지로, Avatar가 이러한 props를 사용하는 방법을 변경할 수 있으며 Profile을 확인하지 않아도 됩니다.
Props를 "버튼"으로 생각할 수 있습니다. 함수의 인수와 마찬가지로, props는 컴포넌트의 유일한 인수입니다! 리액트 컴포넌트 함수는 단일 인수, 즉 props 객체를 허용합니다.
function Avatar(props) {
let person = props.person;
let size = props.size;
// ...
}
일반적으로 전체 props 객체 자체가 필요하지 않기 때문에 개별적인 props로 분해합니다.
props를 선언할 때 (
와 )
사이에 있는 {
와 }
중괄호 쌍을 놓치지 마세요.
function Avatar(
{ person, size }) {
// ...
}
이 구문은 해체 할당이라고 하며, 함수 매개변수에서 속성을 읽는 것과 동일합니다.
function Avatar(props) {
let person = props.person;
let size = props.size;
// ...
}
props에 기본값 지정하기
값이 지정되지 않았을 때 기본값을 props에 지정하려면, 파라미터 바로 뒤에 =와 기본값을 넣는 해체 할당을 사용할 수 있습니다.
function Avatar({ person, size = 100 }) {
// ...
}
이제 size prop이 없이 <Avatar person={...} />
로 렌더링되면 size는 100으로 설정됩니다.
기본값은 size prop이 누락되었거나 size={undefined}
로 전달된 경우에만 사용됩니다. 그러나 size={null}
또는 size={0}
과 같이 전달하는 경우 기본값은 사용되지 않습니다.
JSX 스프레드 구문을 사용하여 props 전달하기
가끔씩 props를 전달하는 것이 매우 반복적일 수 있습니다.
function Profile({ person, size, isSepia, thickBorder }) {
return (
<div className="card">
<Avatar
person={person}
size={size}
isSepia={isSepia}
thickBorder={thickBorder}
/>
</div>
);
}
반복적인 코드는 문제가 없습니다. 가독성이 좋을 수도 있습니다. 그러나 때로는 간결함을 더 중요시할 수 있습니다. 일부 컴포넌트는 Avatar와 같이 모든 props를 자식 컴포넌트로 전달합니다. 그들은 직접 props 중 하나도 사용하지 않기 때문에 더 간결한 "스프레드" 구문을 사용하는 것이 의미가 있을 수 있습니다.
function Profile(props) {
return (
<div className="card">
<Avatar {...props} />
</div>
);
}
이렇게 하면 Profile의 모든 props가 개별적으로 나열되지 않고도 Avatar에 모두 전달됩니다.
스프레드 구문을 사용할 때는 분별하여 사용하세요. 거의 모든 컴포넌트에서 사용하고 있다면 문제가 있을 수 있습니다. 종종 컴포넌트를 분할하고 자식을 JSX로 전달해야 하는지 확인해야 합니다. 이에 대해서는 곧 자세히 알아보겠습니다!
자식으로 JSX 전달하기
내장된 브라우저 태그를 중첩하는 것이 일반적입니다.
<div>
<img />
</div>
자체 컴포넌트도 동일한 방식으로 중첩할 때가 있습니다.
<Card>
<Avatar />
</Card>
JSX 태그 내에 콘텐츠를 중첩할 때, 부모 컴포넌트는 해당 콘텐츠를 children이라는 prop으로 수신합니다. 예를 들어, 아래의 Card 컴포넌트는 children prop으로 <Avatar />
를 받아서 래퍼 div 안에서 렌더링합니다.
<Avatar>
을 <Card>
안에 있는 일부 텍스트로 바꿔보면 Card 컴포넌트가 중첩된 콘텐츠를 어떻게 감쌀 수 있는지 확인할 수 있습니다. Card는 그 안에 렌더링되는 내용을 "알 필요"가 없습니다. 이 유연한 패턴은 많은 곳에서 볼 수 있습니다.
컴포넌트에 children prop이 있는 것은 부모 컴포넌트에 의해 임의의 JSX로 "채워질 수 있는" "빈 공간"이 있는 것으로 생각할 수 있습니다. 일반적으로 children prop을 시각적인 래퍼 (패널, 그리드 등)에 사용합니다.
props가 시간에 따라 어떻게 변경되는지
아래의 Clock 컴포넌트는 부모 컴포넌트로부터 두 가지 props를 받습니다. color와 time (부모 컴포넌트의 코드는 생략되었습니다. 이 코드는 상태를 사용하며, 현재는 자세히 설명하지 않을 예정입니다.)
아래의 선택 상자에서 색상을 변경해 보세요:
이 예제는 컴포넌트가 시간이 지남에 따라 다른 props를 받을 수 있다는 것을 보여줍니다. Props는 항상 정적이지 않습니다! 여기에서는 time prop이 1초마다 변경되고, color prop은 다른 색상을 선택할 때 변경됩니다. Props는 단지 컴포넌트의 데이터를 나타내는 것뿐만 아니라 어느 시점에서든 컴포넌트의 데이터를 반영합니다.
그러나 props는 변경할 수 없는 불변이라는 컴퓨터 과학 용어입니다. 컴포넌트가 props를 변경해야 하는 경우 (예: 사용자 상호 작용 또는 새 데이터에 대한 응답으로) 부모 컴포넌트에게 다른 props (새 객체)를 전달해야 합니다! 그리고 예전 props는 버려지고, 결국 JavaScript 엔진이 그들이 사용한 메모리를 회수할 것입니다.
props를 "변경하려고 하지 마세요". 사용자 입력에 대응해야 할 때 (예: 선택한 색상 변경) props를 "설정"해야 합니다. 이에 대해서는 상태: 컴포넌트의 메모리에서 알아보실 수 있습니다.
요약
- props를 전달하려면 HTML 속성과 마찬가지로 JSX에 추가합니다.
- props를 읽으려면
function Avatar({ person, size })
해체 구문을 사용합니다. - 누락된 및 undefined props에 대한 기본값으로
size = 100
과 같이 기본값을 지정할 수 있습니다. - JSX 스프레드 구문인
<Avatar {...props} />
를 사용하여 모든 props를 전달할 수 있지만, 과용하지 않도록 주의하세요! <Card><Avatar /></Card>
와 같이 중첩된 JSX는 Card 컴포넌트의 children prop으로 나타납니다.- Props는 시간에 따라 변경됩니다. 각 렌더링은 새로운 버전의 props를 받습니다.
- props를 "변경하려고"하지 마세요. 사용자 상호 작용에 응답해야 할 때는 "상태를 설정"해야 합니다.