programming/React

React. 컴포넌트 만들기, Props, state

dmchoi 2021. 2. 18. 01:11

※본 포스팅은 생활코딩님의 리액트 강의를 바탕으로 작성한 글입니다.

컴포넌트 만들기

HTML로 코드를 작성했을 때

 

<html>
  <body>
      <header>
          <h1>WEB</h1>
          world wide web!
      </header>

      <nav>
          <ul>
              <li><a href="1.html">HTML</a></li>
              <li><a href="2.html">CSS</a></li>
              <li><a href="3.html">JavaScript</a></li>
          </ul>
      </nav>

      <article>
          <h2>HTML</h2>
          HTML is Hyper Text Markup Language.
      </article>
  </body>
</html>

 

컴포넌트를 만드는 코드

 

class App extends Component {
  render() {
    return (
      <div className="App">
        Hello, React!
      </div>
    )
  }
}

 

리액트가 가지고 있는 컴포넌트라는 클래스를 상속해서 새로운 App라는 클래스를 만든다

그리고 그 클래스는 render라는 매서드를 가지고 있다.

 

 

위 HTML 코드를 React로 정리하면

 

class Subject extends Component { 
    render() {	
        return (
            <header>
                <h1>WEB</h1>
                world wide web!
            </header>
        );
    }
}

class TOC extends Component {
    render() {
        return (
            <nav>
                <ul>
                    <li><a href="1.html">HTML</a></li>
                    <li><a href="2.html">CSS</a></li>
                    <li><a href="3.html">JavaScript</a></li>
                </ul>
            </nav>
        );
    }
}

class Content extends Component {
    render() {
        return (
            <article>
                <h2>HTML</h2>
            	HTML is Hyper Text Markup Language.
            </article>
        );
    }
}

class APP extends Coponent {
    render() {
        return (
            <div className="App">
                <Subject></Subject>
                <TOC></TOC>
                <Content></Content>
            </div>
        );
    }
}

 

자바스크립트 최신 문법에선 클래스 안에 들어가는 함수는 function 생략 가능하다.

컴포넌트를 만들 때는 반드시 하나의 최상위 태그를 가져야한다.

 

<Subject>, <TOC>와 같은 컴포넌트 이름에만 집중하게 함으로써 복잡도를 획기적으로 낮춤

 

위의 코드는 JSX로 자바스크립트랑 유사하게 생겼지만 자바스크립트는 아니다.

JSX로 코드를 작성하면 Create react app이 알아서 자바스크립트 코드로 변환해 줌

 

Props

html에서는 속성을 attribute라 하고 리액트에서 속성은 props라 함

 

컴포넌트에 속성을 부여하고 {this.props.속성이름}로 조회

 

class Subject extends Component {
  render() {
    return (
      <header>
        <h1>{this.props.title}</h1>
      {this.props.sub}
      </header>
    );
  }
}

 

Subject라는 컴포넌트는 언제나 똑같은 값을 출력해주는 것이었는데, title, sub와 같은 속성을 부여해 차별화를 준다. 이는 컴포넌트의 입력값이 됨으로써 다른 값을 출력할 수 있게 됨 -> 재사용성이 높아진다.

 

class App extends Component {
  render() {
    return (
      <div className="App" >
        <Subject title="WEB" sub="world wide web!"></Subject>
        <Subject title="React" sub="For UI"></Subject>
        <TOC></TOC>
        <Content title="HTML" desc="HTML is Hyper Text Makrup Language."></Content>
      </div>
    );
  }
}

 

컴포넌트 파일로 분리하기

수 많은 컴포넌트들이 하나의 파일 안에 있다면 얼마나 복잡할까?

 

각 컴포넌트들을 파일로 분리하면 코드가 간결해지고 필요한 컴포넌트를 빨리 찾을 수 있게 된다.

또한 다른 리액트 파일에서도 컴포넌트들을 재사용 할 수 있다.

 

src 디렉토리에 components 디렉토리를 생성

이 안에 각각의 컴포넌트 별로 파일을 만든다.

 

TOC.js 

 

import React, { Component } from 'react'; // 컴포넌트를 TOC.js 안에 쓰기 위해 리액트를 불러오는 코드

class TOC extends Component {
    render() {
        return (
            <nav>
                <ul>
                    <li><a href="1.html">HTML</a></li>
                    <li><a href="2.html">CSS</a></li>
                    <li><a href="3.html">JavaScript</a></li>
                </ul>
            </nav>
        );
    }
}

export default TOC;  // 이 코드로 인해서 TOC라는 클래스를 가져다 사용할 수 있게 됨

import React, { Component } from 'react'; // 리액트라는 라이브러리에서 컴포넌트라는 클래스를 로딩. 이를 밑에 component가 사용함

 

App.js

컴포넌트를 App.js으로 불러오는 코드

import TOC from "./components/TOC";
import Content from "./components/Content";
import Subject from "./components/Subject";

 

이후 App.js에 있던 TOC, Content, Subject 컴포넌트를 지워준다.

 

결과는 똑같지만 코드는 훨씬 보기 좋아진다.

 

State

Props는 사용자가 컴포넌트를 사용하는 입장에서 중요한 것이고, 
State는 그 props의 값에 따라 내부의 구현에 필요한 데이터들, 사용자는 알 필요없는 컴포넌트 내부적으로 사용되는 것들 

리액트와 같은 시스템이 컴포넌트를 만들고 그 컴포넌트가 좋은 부품이 되기 위해선 그 컴포넌트를 사용하는 외부의 props와 props에 따라 컴포넌트를 실제 구현하는 내부의 state라는 정보가 철저하게 분리 되어있어야한다. 

 

사용하는 쪽과 구현하는 쪽 양쪽의 편의성을 각자 도모하는 것이 좋은 부품을 만드는 것의 핵심이고 리액트도 마찬가지이다.

state는 실제 컴포넌트를 구현할 때, 더 복합적으로 다양한 일들을 하는 컴포넌트를 만들 때 필요한 필수적인 요소

 

 

props를 쓰기 위해선 다음과 같은 코드가 필요함

 

어떠한 컴포넌트가 실행될 때 render 함수보다 먼저 실행이 되면서 그 컴포넌트를 초기화 시켜줌

 

class App extends Component{
  constructor(props){
      super(props);
      this.state ={ // state 값을 초기화
      subject : {title : 'WEB', sub : 'World Wide Web!'}
   }
 }
 
 render() {
    return (
      <div className="App" >
        <Subject title={this.state.subject.title}
          sub={this.state.subject.sub}>
        </Subject>
      </div>
    );
  }
}

 

1. State 값을 초기화
2. subject의 프로퍼티값으로 'WEB'과 'World Wide Web'을 줌

3. 상위 컴포넌트 App의 state 값을 하위 컴포넌트의 props 값으로 전달

 

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css'; 
import App from './App';
import reportWebVitals from './reportWebVitals';

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


reportWebVitals();

 

index.js를 보는 우리 입장에선 <App/>가 내부적으로 state값이 subject가 있는지 없는지 알수가 없다. 외부에서 알 필요가 없는 정보를 철저하게 은닉하는 것이 좋은 사용성을 만든다.