ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 리액트 주요개념 - Component와 Props
    IT/리액트 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

    'IT > 리액트' 카테고리의 다른 글

    리액트 주요개념 - 이벤트 처리하기  (0) 2022.01.15
    리액트 주요개념 - State and Lifecycle  (0) 2022.01.15
    리액트 주요개념 - 엘리먼트 렌더링  (0) 2022.01.15
    리액트 주요개념 - JSX  (0) 2022.01.12
    리액트 개요  (0) 2022.01.12

    댓글

Designed by Tistory.