Back Ground

React - 컴포넌트 [props , state] 본문

Javascript/React.js

React - 컴포넌트 [props , state]

Back 2018. 10. 19. 18:50


컴포넌트란?
컴포넌트는 프로그래밍의 한 부분을 의미하며 재사용이 가능한 최소 단위를 말한다. 그래서 객체지향언어를 사용할 때 자주 사용되며 재사용이 가능하기 때문에 컴포넌트 단위로 분류하거나 이동 가능하다는 특징이 있다.

이는 모듈(Module)과 혼동될 수 있는데 모듈은 특정 기능을 온전히 수행할 수 있도록 만들어 졌다면 그 모듈 내에서도 재사용이 가능한 단위가 컴포넌트라 할 수 있다.

웹사이트를 구축할 경우 모든 것을 새로 만드는 웹 사이트를 상상조차 할 수 없는게 현실이다. 대부분이 라이브러리, 플러그인, 모듈 그리고 컴포넌트로 재사용이 되는 부분들이 대단히 많다 하겠으며 이를 얼만큼 효과적으로 가장 적합한 어떤 것을 찾고 적용하는 역량이 더 중요해졌다 말할 수 있다.


출처 : https://webisfree.com/2015-12-02/%EC%9B%B9%EC%97%90%EC%84%9C-%EB%A7%90%ED%95%98%EB%8A%94-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80





src 디렉토리에


MyComponent.js 를 만들었다. (되도록 파일명은 Class이름과 동일하게 만든것을 권장)

1
2
3
4
5
6
7
8
9
10
11
12
13
import React ,{Component , Fragment} from 'react';
 
class MyComponent extends Component{
    render(){
        return (
            <Fragment>
                안녕하세요 {this.props.abcd}
            </Fragment>
        )
    }
}
 
export default MyComponent;
cs

이렇게 컴포넌트를 작성했다면 


이 모듈을 사용하기 위해

내보내기 (export) 를 해야 한다.


export default MyComponent;


단 하나의 모듈을 내보내기 위할때 default를 쓰고 그렇지않으면 { 컴포넌트 }를 사용하면 되지만

이는 나중에 설명하도록 하고



개발 구조에 따라 다르겠지만

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
export default class TestComponent extends React.Component{
    render(){
        return(
            <React.Fragment>
                <span>
                    Test 용도
                </span>
                <br/>
                <span>
                    {this.props.test}
                </span>
            </React.Fragment>
        )
    }
};
cs

이렇게 class 자체를 export 해주어도 된다.




받을땐 import로 받으면 된다.



App.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
import React, { Component ,Fragment} from 'react';
import MyComponent from './MyComponent';
 
class App extends Component {
  render() {
    const var1 = '1변수';
    const var2 = '2변수';
    const codition = true;
    
    return (
      <Fragment>
        
          <div className="App">
            {var1}
          </div>
            {codition ? '참' : '거짓'}
          <div>
            {var2}
          </div>
          <MyComponent abcd='React' />
 
      </Fragment>
    );
  }
}
 
export default App;
 
cs





props

props는 properties를 줄인 표현으로 컴포넌트 속성을 설정할 때 사용하는 요소이다.

props값은 해당 컴포넌트를 불러와 사용하는 부모 컴포넌트 (현재 부모 App)에서 설정 할 수 있다.



MyComponent.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import React ,{Component , Fragment} from 'react';
import PropTypes from 'prop-types';
 
class MyComponent extends Component{
    render(){
        return (
            <Fragment>
                안녕하세요 {this.props.abcd}
            </Fragment>
        )
    }
}
 
export default MyComponent;
cs
import PropTypes from 'prop-types';를 추가하면

this.props.abcd와 같이
propsthis키워드를 사용하여 접근한다


props 설정은 Html과 비슷하다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import React, { Component ,Fragment} from 'react';
import MyComponent from './MyComponent';
 
class App extends Component {
  render() {
    return (
      <Fragment>
          <MyComponent abcd='React' />
      </Fragment>
    );
  }
}
 
export default App;
 
cs

이렇게 adcd 라는 키에 넣어주면


결과

안녕하세요 React  

가 나오게 된다







- props 기본값 설정 ( defualtProps )

props가 undefined또는 null 이거나 비어있을때 기본값을 설정할 수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import React ,{Component , Fragment} from 'react';
import PropTypes from 'prop-types';
 
class MyComponent extends Component{
    static defaultProps = {
        abcd : 'Angular',
    }
    static propTypes ={
        abcd : PropTypes.string,
    }
    render(){
        return (
            <Fragment>
                안녕하세요 {this.props.abcd}
            </Fragment>
        )
    }
}
 
export default MyComponent;
cs


이렇게 defualtProps 를 사용하게 되면 기본값을 설정할 수 있다.








props 검증 (propTypes) 

static propTypes ={
        abcd : PropTypes.string,
    }

이렇게 데이터타입을 지정 하면 

Dom에선 제대로 보이지만

개발자 도구를 열면 type이 다르다는 에러가 뜨는것을 확인 할수있다.



만일 number를 입력 하려면 스코프에 정의 해야된다.

1
<MyComponent abcd={3/>
cs

잘못된 방식 

1
<MyComponent abcd=3 />
cs





state

props는 부모 컴포넌트가 설정하고

컴포넌트 자신의 해당 props를 읽기전용으로 사용할 수 있었다.


컴포넌트 내부에서 읽고 또 업데이트 할 수 있는 값을 사용하려면

state 써야 한다.


이건 언제나 기본값을 미리 설정해야 사용할수 있다!


업데이트하려면 this.setState()메서드에 값을 업데이트 할 수 있다.




컴포넌트 새성자 : constructor()


state 초기값은 컴포터는 생성자 메소드인 constructor() 내부에 설정해야 한다


생성자 메서드는 컴포넌트를 새로 만들때 실행된다 (라이프사이클 중 하나  자세한건 나중에 설명한다.)


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
import React ,{Component , Fragment} from 'react';
import PropTypes from 'prop-types';
 
class MyComponent extends Component{
    static defaultProps = {
        abcd : 'Angular',
    }
    static propTypes ={
        abcd : PropTypes.string,
    }
 
    constructor(props){
        super(props);
        this.state ={
            num : 0,
        }
    }
 
    render(){
        return (
            <Fragment>
                안녕하세요 {this.props.abcd}
            </Fragment>
        )
    }
}
 
export default MyComponent;
cs


Component Class안에 construtor()가 있기 때문에 반드시 확장을 시켜주어여 한다.

construtor()를 사용할때 super()메소드를 통해 

컴포넌트를 만들때 props값을 사용하기에 props를 메서드로 보낸다.


그리고 super()전에 

this를 사용하면 안된다. 


여기에는 여러가지 의문이 드는데 




1. constructor안에 super()를 꼭 불러야 하는가?

super()전에 this가 허용되지 않는 이유는

super()가 불리지않으면 this가 초기화 되지않는기 때문이다.


React.Component.construtor로 확장한 subClass( extends Component )가 있다면 무조건 super()를 불러야한다.

따라서 코드에 constructor가 있는한 반드시 super()를 불러야한다.( 없으면 에러 )

(하지만 subClass는 constuctor를 반드시 가지지 않아도 상관없다. 

즉 MyComponent의 Component를 확장한 constructor()는 필요할때 사용하면 된다는 뜻 )





2. super()를 부르는것과 super(props)를 부르는것의 차이는?

construtor안에 this.props 접근하고 싶을때만 super(props)를 불러야한다.

다른곳에서 (construtor가 아닌) this.props를 사용하고 싶은거라면

constructor안에 props를 넘겨줄 필요없다.

왜냐면 React가 자동으로 셋팅 해준다!


1
2
3
4
5
    constructor(props){
        super(props);
        console.log(this.props.abcd)
    }
 
cs





state 초기값 설정

1
2
3
4
5
6
7
    constructor(props){
        super(props);
        console.log(this.props.abcd)
        this.state ={
            num : 0,
        }
     }
cs

생성자constructor 메소드 안에 state를 초기값을 지정한다.



JSX내부에서 state 랜더링하면 되는데

props를 랜더링할때와 비슷하다.



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
import React ,{Component , Fragment} from 'react';
import PropTypes from 'prop-types';
 
class MyComponent extends Component{
    static defaultProps = {
        abcd : 'Angular',
    }
    static propTypes ={
        abcd : PropTypes.string,
    }
 
    constructor(props){
        super(props);
        console.log(this.props.abcd)
        this.state ={
            num : 0,
        }
    }
 
    render(){
        return (
            <Fragment>
                안녕하세요 {this.props.abcd}
                <br/>
                여긴 state 값이 출력됩니다. {this.state.num}
            </Fragment>
        )
    }
}
 
export default MyComponent;
cs


이렇게 랜더링 하면된다.




state 값 업데이트 : setState()

state값을 업데이트할 때는 this.setState() 메서드사용하면 된다.


1
2
3
4
this.setState({
   수정할 필드 이름 : 값,
   수정할 또는 다른필드 이름 : 값
});
cs





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
import React ,{Component , Fragment} from 'react';
import PropTypes from 'prop-types';
 
class MyComponent extends Component{
    static defaultProps = {
        abcd : 'Angular',
    }
    static propTypes ={
        abcd : PropTypes.string,
    }
 
    constructor(props){
        super(props);
        console.log(this.props.abcd)
        this.state ={
            num : 0,
        }
    }
 
    render(){
        return (
            <Fragment>
                안녕하세요 {this.props.abcd}
                <br/>
                여긴 state 값이 출력됩니다. : {this.state.num}
                <button onClick={()=> { 
                        this.setState({
                            num:this.state.num + 1
                        })
                    }
                }></button>
 
            </Fragment>
        )
    }
}
 
export default MyComponent;
cs


버튼을 누를떄마다 this.setState()가 실행되어서 state에 업데이트 할 수 있다.




state를 constructor내부에 사용하지않는 방법

import PropTypes from 'prop-types';

을 사용하면 constructor 바깥에 정의 할 수 있다.


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
import React ,{Component , Fragment} from 'react';
import PropTypes from 'prop-types';
 
class MyComponent extends Component{
    static defaultProps = {
        abcd : 'Angular',
    }
    static propTypes ={
        abcd : PropTypes.string,
    }
 
  
    state = {
       num:0
    }    
 
    render(){
        return (
            <Fragment>
                안녕하세요 {this.props.abcd}
                <br/>
                여긴 state 값이 출력됩니다. : {this.state.num}
                <button onClick={()=> { 
                        this.setState({
                            num:this.state.num + 1
                        })
                    }
                }></button>
 
            </Fragment>
        )
    }
}
 
export default MyComponent;
cs


this.가 아닌 MyComponent.state로 지정해서 사용하면 된다,






'Javascript > React.js' 카테고리의 다른 글

React - ref : DOM에 이름 달기  (0) 2018.10.20
React - 이벤트 핸들링  (0) 2018.10.20
React - JSX  (0) 2018.10.19
React - 프로젝트 생성 및 babel & webpack 설명  (0) 2018.10.19
React - 설치하기  (0) 2018.10.19
Comments