코린이의 기록

[React] 리엑트와 컴포넌트 props & state 본문

Framework/React

[React] 리엑트와 컴포넌트 props & state

코린이예요 2018. 6. 17. 21:30
반응형

컴포넌트?


컴포넌트는 부품이라는 뜻을 가지고 있다. 예를들면 버튼이나 텍스트박스와 같이 범용적으로 사용되는 부품이 컴포넌트이다. 리액트에서도 컴포넌트를 정의하여 일반적인 JSX 태그처럼 사용할 수 있다. 


함수를 기반으로 컴포넌트를 정의하는 방법


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const dom = <div>
        <PhotoText image = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTAzvo3orQ1lcM7zgREJ7Bz2GPESn6Ylvyt8qgCej29K5i8W3Vy5A" label = "오키나와에서의 하루" />
        <PhotoText image = "https://s3-ap-northeast-1.amazonaws.com/okinawaclips3/kr/images/231.jpg" label = "오키나와 해변" />
        <PhotoText image = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS9ecORwUP0yb9UaYfxJGuWjnnHSgbExL-s9eD_MHud1SRAMqbV" label = "푸른 바다" />
        </div>
ReactDOM.render(dom,
               document.getElementById('root'))
 
function PhotoText (props){
  const url = props.image
  //const url = "http://uta.pw/shodou/img/28/214.png"
  const label = props.label
  const boxStyle = {
    border : "1px solid silver",
    margin : "8px",
    padding : "4px"
  }
  return <div style={boxStyle}>
    <img src={url} width="128" />
    <span>{label}</span>
    </div>
}
cs


line 1 : PhotoText 컴포넌트를 사용

line 9 : PhotoText 컴포넌트를 정의


결과화면



클래스 기반으로 컴포넌트를 정의하는 방법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class PhotoText extends React.Component{
  
  getImageURL (){
    const id = this.props.image
    const url = id
    return url;
  }
  
  render(){
    const label = this.props.label
    const url = this.getImageURL()
    const boxStyle = {
      border : "1px solid silver",
      margin : "8px",
      padding : "4px"
    }
    
    return (<div style={boxStyle}><img src={url} width="128"/> 
        <span> {label} </span>
        </div>)
  }
}
 
const dom = <div>
        <PhotoText image = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTAzvo3orQ1lcM7zgREJ7Bz2GPESn6Ylvyt8qgCej29K5i8W3Vy5A" label = "오키나와에서의 하루" />
        <PhotoText image = "https://s3-ap-northeast-1.amazonaws.com/okinawaclips3/kr/images/231.jpg" label = "오키나와 해변" />
        <PhotoText image = "https://scontent.cdninstagram.com/vp/ba409176a6b2667e37ceb3022ee6efea/5B793A4F/t51.2885-15/s640x640/sh0.08/e35/30890526_716301728760301_5118782958706098176_n.jpg" label = "오키나와 하늘" />
        </div>
ReactDOM.render(dom,
               document.getElementById('root'))
 
 
cs


line 1 : PhotoText 클래스를 정의한다. React.Component라는 리액트의 기본적인 컴포넌트 클래스를 상속받는다.

line 9 : render 메소드의 반환 값이 컴포넌트의 출력 내용이다.

line 24 : 정의된 컴포넌트를 사용하는 부분


결과화면



props? 

- 컴포넌트 내부의 Immutable Data (변하지 않는)

- JSX 내부 : { this.props.propsName } 

- 컴포넌트를 사용할때 : <> 괄호 안에 propsName="value"

- this.props.children은 기본적으로 갖고있는 props로서, <Component>여기에 있는 값이 들어간다.</Component>


props.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<html><head>
  <meta charset="utf-8">
    <!-- 라이브러리를 읽어옴 -->
    <script src="https://unpkg.com/react@15/dist/react.min.js"></script>
    <script src="https://unpkg.com/react-dom@15/dist/react-dom.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.38/browser.min.js"></script>
  </head>
  <body>
    <!-- 요소를 정의한다 -->
    <div id="root"></div>
    <!-- 스크립트 정의 -->
    <script type="text/babel">
      class Codelab extends React.Component{
        render(){
          return(
            <div>
              <h1>Hello {this.props.name}</h1>
              <div>{this.props.children}</div>
            </div>
          );
        }
      }
 
      class App extends React.Component{
        render(){
          return(
            <Codelab name={this.props.name}> {this.props.children} </Codelab>
          );
        }
      }
 
      ReactDOM.render(
      <App name="veloport">I am your child </App>,
      document.getElementById('root')
      )
    </script>
  </body>
</html>
 
cs


결과화면


Props의 기본 값 설정하기

props_default.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<html><head>
  <meta charset="utf-8">
    <!-- 라이브러리를 읽어옴 -->
    <script src="https://unpkg.com/react@15/dist/react.js"></script>
    <script src="https://unpkg.com/react-dom@15/dist/react-dom.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.38/browser.js"></script>
  </head>
  <body>
    <!-- 요소를 정의한다 -->
    <div id="root"></div>
    <!-- 스크립트 정의 -->
    <script type="text/babel">
      class Codelab extends React.Component{
        render(){
          return(
            <div>
              <h1>Hello {this.props.name}</h1>
              <h2>{this.props.number}</h2>
              <div>{this.props.children}</div>
            </div>
          );
        }
      }
 
      Codelab.propTypes = {
        name:React.PropTypes.string,
        number:React.PropTypes.number.isRequired
      };
 
      Codelab.defaultProps = {
        name:'Unknown'
      };
 
      class App extends React.Component{
        render(){
          return(
            <Codelab name={this.props.name} number={this.props.number}> {this.props.children} </Codelab>
          );
        }
      }
 
      ReactDOM.render(
      <App number={5}>I am your child </App>,
      document.getElementById('root')
      )
    </script>
  </body>
</html>
cs


line 25 : Codelab의 props 검증

특정 props가 특정 type이 아니거나, 필수 props인데 입력하지 않았을 경우 개발자 콘솔에서 경고를 띄울 수 있다.

props type 의 종류는 아래 링크에서 더 확인해볼 수 있음

https://reactjs.org/docs/components-and-props.html

line 27 : isRequired 가 들어가면 rendering할때  number 값을 지정해주어야 error 가 발생하지 않는다.

line 30 : Codelab의 defaultProps 로 name 값을 설정해줌

line 43 : props.html 소스에서는 App name="veloport" name을 veloport로 지정해주었는데, props_default.html에서는 생략해주었다. defaultProps에서 name을 'Unknown'으로 지정해주었기 때문에 값을 넣지 않아도 default 값이 출력된다.


결과화면


참고로 isRequired 속성이 들어간 number를 설정해주지 않았을 경우 개발자 콘솔에서 아래와 같은 경고가 발생한다.



※ propsType은 반드시 설정해야하는 것은아니지만, 유지보수를 위해 설정하는 것이 좋다. 

여러개의 컴포넌트를 만들었을 때, 동료 프로그래머가 해당 컴포넌트를 사용하려고 한다.

해당 컴포넌트가 어떤 props를 필요로하고 어떤 type인지 알려면 컴포넌트 코드를 찾아봐야하는데, propTypes를 찾음으로써 더 쉽게 코드를 찾을 수 있다.


state?


- 유동적인 데이터

- JSX 내부에 { this.state.stateName}

- 초기 값 설정이 필수, 생성자 (constructor)에서 this.state ={} 으로 설정

- 값을 수정할 때에는 this.setState({...}), 렌더링 된 다음엔 this.state = 절대 사용하지 말것


counter.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<html><head>
  <meta charset="utf-8">
    <!-- 라이브러리를 읽어옴 -->
    <script src="https://unpkg.com/react@15/dist/react.js"></script>
    <script src="https://unpkg.com/react-dom@15/dist/react-dom.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.38/browser.js"></script>
  </head>
  <body>
    <!-- 요소를 정의한다 -->
    <div id="root"></div>
    <!-- 스크립트 정의 -->
    <script type="text/babel">
 
      class Counter extends React.Component{
        constructor(props){ 
          super(props); 
          this.state = { 
            value:0
          };
          this.handleClick = this.handleClick.bind(this); 
        }
        
        handleClick(){
          this.setState({ 
            value:this.state.value + 1
          });
        }
        render(){
          return(
            <div>
            <h2>{this.state.value}</h2>
            <button onClick={this.handleClick}>Press Me</button>
            </div>
          )
        }
      }
 
      class App extends React.Component{
        render(){
          return(
          <Counter/>
        );
      }
    }
 
      ReactDOM.render(
      <App/>,
      document.getElementById('root')
      )
    </script>
  </body>
</html>
 
cs



line 15 : constructor의 method는 props이다. 카운터가 만들어질 때 전달받은 props

line 16 : super를 통하여 상속받은 클래스인 react component, 즉 parent의 생성자 메소드를 먼저 실행한다. 

그래야 이 메소드 안에서 this.state, props... 를 접근할 수 있다.

line 17 : state 설정에는 초기 값 설정이 필수이다.

line 20 : this 가 무엇인지 바인딩해주는 부분

line 23 : 버튼이 클릭될때 발생하는 메소드

line 24 : javascript에서 임의 메소드를 실행할때는 해당 컴포넌트에서 this가 무엇인지 모름 -> constructor 내에서 바인딩을 해주어야함

line 27 : state 값을 직접 넣어 설정해주는 것은 불가능함. forceUpdate 메소드를 통해서 설정은 가능하나.. 사용하지 않는 것이 좋음..

this.state.value = this.state.value + 1 this.forceUpdate()



컴포넌트 및 props 와 state에 대한 설명으로 아래 링크 참고

http://blog.sonim1.com/177

이 포스팅은 '모던 자바스크립트 개발자를 위한 리액트 프로그래밍' 책 & [React.js] 강좌 (React&Express 를 이용한 웹 어플리케이션 개발하기) 2편을 참고하였습니다. 


반응형
Comments