[React]-Component와 Props

2020. 8. 18. 00:56개발/React

아래 내용은 React Document 를 바탕으로 작성되었습니다.

Component와 Props

컴포넌트를 사용해 UI를 재사용이 가능한 여러 조각으로 나누고 각 조각을 개별적으로 살펴볼 수 있다.

개념적으로 컴포넌트는 JavaScript 함수와 유사하다. props라고 하는 임의의 입력을 받은 후, 화면에 어떻게 표시되는지를 기술하는 React 엘리먼트를 반환한다.


함수 컴포넌트와 클래스 컴포넌트

function Welcome(props){
    return <h1>Hello, {props.name}</h1>
}

이 함수는 데이터를 가진 하나의 props 객체 인자를 받은 후 React 엘리먼트를 반환하므로 유효한 React 컴포넌트이다. 이러한 컴포넌트를 함수 컴포넌트 라고 한다.

또한 ES6 class를 사용하여 컴포넌트를 정의할 수 있다.

class Welcom extends React.Component{
    render(){
        return <h1>Hello, {this.props.name}</h1>
    }
}

React의 관점에서 볼 때 함수형, 클래스형. 두 컴포넌트는 동일하다.


컴포넌트 렌더링

이전까지는 React 엘리먼트를 DOM 태그로 나타내었다.

const element = <div/>;

React 엘리먼트는 사용자 정의 컴포넌트로도 나타낼 수 있다.

const element = <Welcome name="sara" />;

React가 사용자 정의 컴포넌트로 작성한 엘리먼트를 발견하면 JSX 어트리뷰트와 자식을 해당 컴포넌트에 단일 객체로 전달한다. 이 객체를 props라고 한다. 아래 코드를 보면 이해가 갈 것이다.

  • 요약 : 사용자 정의 컴포넌트로 작성한 엘리먼트의 자식을 props으로 넘긴다.
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

const element = <Welcome name="Sara" />;
ReactDOM.render(
  element,
  document.getElementById('root')
);

코드에서 보다시피,

  1. Welcome 은 사용자가 정의한 함수형 컴포넌트이다.
  2. 이 컴포넌트는 JSX를 return 하고 있다.
  3. element 변수에 Welcome 컴포넌트를 넣어주는데, 이때 name이라는 어트리뷰트를 정의해서 저장한다.
  4. Welcome 컴포넌트의 props에 어트리뷰트로 작성된 name 이 전달된다.

Document에 나와있는 설명

  1. <Welcome name="Sara" /> 엘리먼트로 ReactDOM.render()를 호출합니다.
  2. React는 {name: 'Sara'}를 props로 하여 Welcome 컴포넌트를 호출합니다.
  3. Welcome 컴포넌트는 결과적으로 <h1>Hello, Sara</h1> 엘리먼트를 반환합니다.
  4. React DOM은 <h1>Hello, Sara</h1> 엘리먼트와 일치하도록 DOM을 효율적으로 업데이트합니다.

주의 : 컴포넌트의 이름은 항상 대문자로 시작합니다.

React는 소문자로 시작하는 컴포넌트를 DOM 태그로 처리한다.

예를들어 <div /> 는 HTML div 태그를 나타내지만 <Welcome /> 은 컴포넌트를 나타내며 범위 안에 Welcome이 있어야 한다.


컴포넌트 합성

컴포넌트는 다른 컴포넌트를 참조해서 출력할 수 있다. 이는 모든 세부 단계에서 동일한 추상 컴포넌트를 사용할 수 있음을 의미한다.

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

function App() {
  return (
    <div>
      <Welcome name="Sara" />
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);

컴포넌트 추출

컴포넌트를 여러 개의 작은 컴포넌트로 나누는걸 두려워 하지 마라!

다음 Comment컴포넌트를 살펴보자

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>
  );
}

구성 요소들이 모두 중첩 구조로 이루어져 있어서 변경하기 어려울 수 있으며, 각 구성요소들을 개별적으로 재사용하기도 힘들다. 이 컴포넌트에서 몇가지 컴포넌트를 추출해 보겠다.

  • Avatar 컴포넌트

    • function Avatar(props) {
        return (
          <img className="Avatar"
            src={props.user.avatarUrl}
            alt={props.user.name}
          />
        );
      }
    • 여기서 props.authorprops.user로 바꾸도록 했는데, props을 네이밍 할 때는 사용될 context가 아닌, 컴포넌트 자체의 관점에서 짓는걸 권장한다.

  • UserInfo 컴포넌트

    • function UserInfo(props) {
        return (
          <div className="UserInfo">
            <Avatar user={props.user} />
            <div className="UserInfo-name">
              {props.user.name}
            </div>
          </div>
        );
      }
  • 변경된 Comment 컴포넌트

    • 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>
        );
      }
    • 처음보다 훨씬 더 간결해지고 깔끔해졌다.

처음에는 컴포넌트를 추철하는 작업이 지루해 보일 수 있다. 하지만 재사용 가능한 컴포넌트를 만들어 놓는 것은 더 큰 앱에서 작업할 때 두각을 나타낸다. UI 일부가 여러번 사용 되거나 (Button, Panel, Avatar) , UI 일부가 자체적으로 복잡한 (App, FeedStory, Comment) 경우에는 별도의 컴포넌트로 만드는게 좋다.


Props는 읽기 전용이다.

함수 컴포넌트나 클래스 컴포넌트 모두 컴포넌트의 자체 props를 수정해서는 안된다. 다음 Sum함수를 살펴보자.

function sum(a, b){
    return a + b;
}

이런 함수를 순수 함수 라고 한다. 입력값을 바꾸려 하지 않고 항상 동일한 입력값에 대해 동일한 결과를 반환하기 때문이다.

반면 밑의 함수는 순수함수가 아니다.

function withdraw(account, amount){
    account.total -= amount;
}

React는 매우 유연하지만 한가지 엄격한 규칙이 있다.

모든 React 컴포넌트는 자신의 props를 다룰 때 반드시 순수 함수 처럼 동작해야 한다.

props은 읽기 전용이다!

'개발 > React' 카테고리의 다른 글

[React]-리스트와 Key  (0) 2020.08.18
[React]-조건부 렌더링  (0) 2020.08.18
[React]-이벤트 처리하기  (0) 2020.08.18
[React] - 엘리먼트 렌더링  (0) 2020.08.17
[React] - JSX  (0) 2020.08.17