[TIL] React 초급: Component, Props, State

6. Component와 Props

6-1. 기본 Component 생성

  1. App.js파일 안에 class 이름과 함께 Component 정의

    class Subject extends Component {
      
    }
  2. render() {} 함수 필수로 생성

    class Subject extends Component {
      render() {
        
      }
    }
  3. return 작성

    class Subject extends Component {
      render() {
        return (
          <header>
              <h1>WEB</h1>
                World Wide WEB!!
          </header>
        );
      }
    }

6-2. Component의 특징

  • App.js에서 Component를 생성하기 위해 작성한 코드는 JS가 아니라 JS와 유사해 보이는 JSX
  • Component는 복잡도를 줄여준다.
  • 배포된 Component를 다른 프로젝트에도 동일하게 사용할 수 있다.

6-3. Props 활용 방법

Props는 속성(attribute)과 같은 역할을 한다.

import logo from './logo.svg';
import './App.css';
import { Component } from 'react';

class Subject extends Component {
  render() {
    return (
      <header>
          <h1>{this.props.title}</h1>
            {this.props.sub}
      </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>{this.props.title}</h2>
          {this.props.desc}
      </article>
    )
  }
}

class App extends Component {
  render() {
    return (
      <div className="App">
          <Subject title="YAY" sub="React!"></Subject>
          <TOC></TOC>
          <Content title="HTML" desc="HTML is HyperText Markup Language."></Content>
      </div>
    );
  }
}

export default App;
  • props는 확장성에 기여한다.

6-4. Component 분리

  1. 새 JS 파일 생성

  2. 새로 생성한 JS 파일에 class 작성

    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>
          )
        }
      }
  3. Component를 import

    import { Component } from 'react';
    
    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>
          )
        }
      }
  4. 해당 JS파일을 외부에서 사용할 수 있도록 export문 작성

    import { Component } from 'react';
    
    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;
  5. 분리한 Component를 사용할 JS파일에서 불러오는 코드 작성

    import TOC from "./components/TOC";

7. State

7-1. props와 State

  • props: Component의 속성을 조작해서 사용자에게 다르게 보여줄 수 있는 정보
  • State: 사용자에게는 노출되지 않는 Component 내부에서 사용되는 정보
  • Component 구현 시 State와 props는 철저히 분리하여 구현되어야 한다.

7-2. State 사용

class App extends Component {
  constructor(props) {
    super(props);
    this.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>
          <TOC></TOC>
          <Content title="HTML" desc="HTML is HyperText Markup Language."></Content>
      </div>
    );
  }
}
  • constructor: Component가 실행될 때 가장 먼저 실행되어서 초기화를 담당하는 함수
  • 상위 Component인 App의 this.state 내부에서 설정한 props값을 해당 props값을 받아서 보여줄 하위 Component의 props값으로 지정해서 사용

7-2. 여러 개의 하위 Component에 State로 props값을 전달하는 경우

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      subject:{title:'WEB', sub:'World Wide Web'},
      contentsclass App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      subject:{title:'WEB', sub:'World Wide Web'},
      contents:[
        {id:1, title:'HTML', desc:'HTML is HyperText Markup Language'},
        {id:2, title:'CSS', desc:'CSS is for design'},
        {id:3, title:'JavaScript', desc:'JavaScript is for interactive'}
      ]
    }
  }
  render() {
    return (
      <div className="App">
          <Subject title={this.state.subject.title} sub={this.state.subject.sub}></Subject>
          <TOC data={this.state.contents}></TOC>
          <Content title="HTML" desc="HTML is HyperText Markup Language."></Content>
      </div>
    );
  }
}
    }
  }
  render() {
    return (
      <div className="App">
          <Subject title={this.state.subject.title} sub={this.state.subject.sub}></Subject>
          <TOC></TOC>
          <Content title="HTML" desc="HTML is HyperText Markup Language."></Content>
      </div>
    );
  }
}
class TOC extends Component {
    render() {
        var lists = [];
        var data = this.props.data
        var i = 0;
        while(i < data.length) {
            lists.push(<li><a href={"/content/"+data[i].id}>{data[i].title}</a></li>)
            i = i+1;
        }
      return (
        <nav>
            <ul>
                {lists}
            </ul>
        </nav>
      )
    }
  }
  • 반복문을 이용해서 State 내부에 선언한 props값을 받아와서 보여줄 수 있다.

하지만 이 경우에는 에러없이 작동은 되지만, Console에서는 Warning: Each child in a list should have a unique "key" prop. 라는 경고문이 뜬다.

7-3. key

class TOC extends Component {
    render() {
        var lists = [];
        var data = this.props.data
        var i = 0;
        while(i < data.length) {
            lists.push(<li key={data[i].id}><a href={"/content/"+data[i].id}>{data[i].title}</a></li>)
            i = i+1;
        }
      return (
        <nav>
            <ul>
                {lists}
            </ul>
        </nav>
      )
    }
  }
  • 여러 개의 props값 목록을 가져오는 경우에는 유니크한 key값이 필요하다.

좋은 웹페이지 즐겨찾기