class를 생성할 때 this.props라는 표현이 있었다. (2020/04/11 - React (2) - Component)
1
2
3
4
5
6
7
8
9
10
11
|
// function형
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
// class형
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
|
cs |
props는 property의 줄임말로 함수에서 parameter로 해당 attribute를 받아 사용할 수 있다.
.(점)으로 속성명에 접근이 가능하고, props.속성명으로 속성 값을 가져올 수 있다.
props의 가장 중요한 특징은 읽기 전용(read-only)이라는 것이다. 어떤 컴포넌트에서든 props 자체를 수정해서는 안된다. (state 글에서 다시 설명하겠다)
컴포넌트는 재사용한 단위로 쪼개는 것이 좋다.
그래서 한 웹사이트에서도 수 십개의 컴포넌트로 쪼개질 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
function Comment(props) {
return (
<div className="Comment">
<div className="UserInfo">
<img className="Avatar"
src={props.author.avatarUrl}
alt={props.author.name}
/>
<div className="UserInfo-name">
{props.author.name}
</div>
</div>
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
|
cs |
Comment 컴포넌트는 author(객체), text(문자열), date(날짜)를 props로 받은 후, SNS의 코멘트에 나타난다.
이 컴포넌트는 모두 중첩 구조로 이루어져 있어 변경하기가 어렵고, 개별적인 재사용도 힘들다. 때문에 재사용 할 수 있는 뭉텅이는 쪼갤 수 있을 때까지 쪼개는 것이 좋다.
위의 Comment 컴포넌트는 각 div별로 쪼갤 수 있다.
우선 가장 안에 있는 Avatar먼저 쪼개겠다.
1
2
3
4
5
6
7
8
|
function Avatar(props) {
return (
<img className="Avatar"
src={props.user.avatarUrl}
alt={props.user.name}
/>
);
}
|
cs |
Avatar는 자신이 Comment 내에서 렌더링 된다는 것을 알 필요가 없으므로, props의 이름을 author에서 user로 변경했다. (props의 이름은 사용될 context가 아닌 컴포넌트 자체의 관점에서 짓는 것을 권장한다.)
그렇다면 전체적인 코드는 아래처럼 바뀐다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
function Comment(props) {
return (
<div className="Comment">
<div className="UserInfo">
<Avatar user={props.author} />
<div className="UserInfo-name">
{props.author.name}
</div>
</div>
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
|
cs |
Avatar에서 user라는 프로퍼티를 {props.author}로 정의한 것이다.
그 후, 사용자 이름을 렌더링 하는 UserInfo div를 class로 빼낸다.
1
2
3
4
5
6
7
8
9
10
|
function UserInfo(props) {
return (
<div className="UserInfo">
<Avatar user={props.user} />
<div className="UserInfo-name">
{props.user.name}
</div>
</div>
);
}
|
cs |
그럼 코드는 아래와 같이 줄여질 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
function Comment(props) {
return (
<div className="Comment">
<UserInfo user={props.author} />
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
|
cs |
밑에서 위로 타고 올라가면 왜 Comment 컴포넌트의 UserInfo에서 user={props.author}이었던 것이, UserInfo 컴포넌트에서는 user={props.user}로 바뀌었는지 이해하기 수월해 질 것이다.
컴포넌트의 props 값을 이어서 생각하지 않고, 하나의 컴포넌트에서 props의 역할이 끝난다 생각하면 된다.
Comment 컴포넌트에서는 <UserInfo />에서 user 프로퍼티에 {props.author}를 정의하면서, props.author의 역할은 끝났다. 마찬가지로 UserInfo 컴포넌트에서 user 프로퍼티에 {props.user}를 정의하면서 해당 컴포넌트에서의 역할도 끝났다. 그 후, <Avatar user={props.user} />로 값을 주었기 때문에 안에서 그대로 {props.user}로 사용할 수 있는 것이다.
완성된 코드
See the Pen qBOEgQz by howdy-mj (@howdy-mj) on CodePen.
'■ 프로그래밍 > React' 카테고리의 다른 글
React Lifecycle(생명 주기) (0) | 2020.04.12 |
---|---|
State (0) | 2020.04.12 |
[React/에러] Module not found: Can't resolve './node_modules/react' (0) | 2020.04.12 |
Component(컴포넌트) (0) | 2020.04.11 |
JSX (0) | 2020.04.10 |