본문 바로가기

■ 프로그래밍/React

Props

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