IT/리액트

리액트 주요개념 - Component와 Props

hanlabong 2022. 1. 15. 01:10
728x90

컴포넌트는 JavaScript 함수와 유사합니다. props(임의의 입력)을 받은 후 React Element(화면에 어떻게 표시되는지 기술)반환합니다.

 

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

컴포넌트를 정의하는 가장 간단한 벙법: JavaScript 함수 작성

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

위의 함수는 데이터를 가진 객체 인자를 받은 후 React 엘리먼트를 반환하기 때문에 유효한 React 컴포넌트입니다.

이러한 컴포넌트는 JavaScript 함수이기 때문에 함수 컴포넌트라고 호칭합니다.

 

또한, ES6 class를 사용하여 컴포넌트를 정의할 수 있는데 React 관점에서 볼 때 위, 아래 두 가지 유형의 컴포넌트는 동일합니다.

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

 

컴포넌트 렌더링

지금까지 DOM 태그만을 사용해 React 엘리먼트를 나타냈는데 React 엘리먼트는 사용자 정의 컴포넌트로도 나타낼 수 있습니다.

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

React가 사용자 정의 컴포넌트로 작성한 엘리먼트를 발견하면 JSX 속성과 자식을 해당 컴포넌트에 단일 객체로 전달하며 이 객체를 props라고 합니다.

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

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

ReactDOM.render(
  element,
  document.getElementById('root')
);

결과:

 

 

 

  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을 효율적으로 업데이트
컴포넌트의 이름은 항상 대문자!!!로 시작합니다.
저는 소문자로 쓰고 실행이 안되서 한참 찾았어요...ㅜㅜ
 

컴포넌트 합성

컴포넌트는 자신의 출력에 다른 컴포넌트를 참조할 수 있습니다.

=> 모든 세부 단계에서 동일한 추상 컴포넌트를 사용할 수 있음을 의미

//Welcome을 여러 번 렌더링하는 App 컴포넌트 만들기

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

 

 

컴포넌트 추출

function formatDate(date) {
  return date.toLocaleDateString();
}

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

const comment = {
  date: new Date(),
  text: 'I hope you enjoy learning React!',
  author: {
    name: 'Hello Kitty',
    avatarUrl: 'https://placekitten.com/g/64/64',
  },
};
ReactDOM.render(
  <Comment
    date={comment.date}
    text={comment.text}
    author={comment.author}
  />,
  document.getElementById('root')
);

위의 comment 컴포넌트는 author, text, date를 props로 받은 후 소셜 미디어 웹 사이트의 코멘트를 나타냅니다.

해당 컴포넌트는 구성요소들이 모두 중첨 구조로 이루어져 있어 변경하기 어려울 수 있고 각 구성 요소를 개별적으로 재사용하기도 힘듭니다. 따라서 몇 컴포넌트를 추출하는 것이 좋습니다.

 

우선 Avatar를 추출합니다.

function Avatar(props) {
  return (
    <img className="Avatar"
      src={props.user.avatarUrl}
      alt={props.user.name}
    />
  );
}

Avatar 컴포넌트는 자신이 Comment 내에서 렌더링 된다는 것을 알 필요가 없기 때문에 props의 이름을 author에서 더욱 일반화된 user로 변경하였습니다.

props의 이름은 사용될 context가 아닌 컴포넌트 자체의 관점에서 짓는 것을 권장!

 

그 결과 Comment가 조금 단순해진 것을 확인할 수 있습니다.

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

 

그 다음 UserInfo 컴포넌트 추출

function UserInfo(props) {
  return(
    <div className='UserInfo'>
      <Avatar user={props.author} />
        <div className="UserInfo-name">
          {props.author.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 일부가 여러 번 사용되거나 UI 일부가 자체적으로 복잡한 경우에는 별도의 컴포넌트로 만드는게 좋습니다!

 

props는 읽기 전용입니다.

함수 컴포넌트나 클래스 컴포넌트 모두 컴포넌트의 자체 props를 수정해서는 안됩니다.

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

위와 같은 함수를 순수 함수라고 합니다. 입력값을 바꾸지 않고 항상 동일한 입력값에 대해 동일한 결과를 반환하기 때문입니다.

그러나 아래의 함수는 자신의 입력값을 변경하기 때문에 순수 함수라고 할 수 없습니다.

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

React에서 반드시 지켜야 할 규칙은

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

입니다.

728x90