티스토리 뷰

React

[React] props & state

ljy98 2022. 4. 13. 13:53

1. props

2. state


오늘은 React의 props와 state에 대해서 알아보려고 한다.

 

[그림 1] props와 state

아직 위의 그림만 보았을 때에는 props와 state가 무엇인지, 어떤 역할을 하는지 추측하기 어려울 수도 있다. 아래 개념 설명을 본 후 이해했다면, 나중에는 위 그림만 보고 '아, props와 state의 차이가 이거였지!' 라고 말하게 될 것이다.

 

 

1. props

props는 properties의 줄임말로, 어떠한 값을 컴포넌트에게 전달해주어야 할 때 사용한다.

 

아래의 코드를 예로 들어서 설명하겠다.

<div id="root"></div>
<script type="text/babel">
    class Input extends React.Component{
        render() {
            return(
                <input type="text" value={this.props.value}/>
            )
        }
    };
    class App extends React.Component{
        render() {
            const Ele = React.createElement(
                'div',
                {
                    value:1,
                    name:'jenny',
                    age:25,
                    class:'header',
                    id:'wrapper'
                },
                'hello world'
            );
            return(<div>{Ele}<Input value={2} /></div>)
        }
    };
    ReactDOM.render(<App/>, document.querySelector('#root'));
</script>

id가 root인 <div> 태그 안에 <App/> 컴포넌트를 넣고, 그 안에 <Input/> 컴포넌트를 넣고자 한다.

 

App 컴포넌트에서 Ele를 선언할 때 React.createElement()를 사용했는데, () 안에는 3개의 인자값이 들어간다. 인자값은 각각 순서대로 엘리먼트의 이름, 엘리먼트의 속성, 엘리먼트 하위의 내용 이다.

 

App 컴포넌트 하위에 Input 컴포넌트의 value 값을 2로 지정해주고자 한다. 먼저 App 컴포넌트의 return 값에 value={2}라고 적는데, Input 컴포넌트의 value라는 속성의 속성값이 2라는 뜻이다. (<input/> 엘리먼트의 value가 2라는 뜻이 아니다.)

 

이제 Input 컴포넌트를 선언한 곳에서 <input/> 태그의 value가 2가 되도록 하려고 하는데, 이때 this.props.value를 이용한다.

 

[그림 2] 브라우저에 나타난 Elements

브라우저에는 hello world라는 내용을 감싼 <div> 태그와 그 속성들이 잘 나타났고, <input/> 태그의 value 값도 2로 되어 있다.

 

[그림 3] 브라우저에 보여지는 모습

 

props에 관련된 예시를 하나 더 살펴보도록 하겠다.

<div id="root"></div>
<script type="text/babel">
    class C extends React.Component{
        render() {
            const {value} = this.props;
            return(<div>{value}</div>)
        }
    };
    class D extends React.Component{
        render() {
            const {value} = this.props;
            return(<div>{value}</div>)
        }
    };
    class A extends React.Component{
        render() {
            const {name} = this.props;
            return(<C value={name}/>)
        }
    };
    class B extends React.Component{
        render() {
            const {name} = this.props;
            return(<D value={name}/>)
        }
    };
    class App extends React.Component{
        render() {
            const text = 'jenny';
            return(
                <React.Fragment>
                    <A name={text}/>
                    <B name={text}/>
                </React.Fragment>
            )
        }
    };
    ReactDOM.render(
        <App/>,
        document.querySelector('#root')
    );
</script>

먼저 구조를 설명하자면, App 컴포넌트 하위에 A,B 컴포넌트가 있고, A 컴포넌트 하위에 C가, B 컴포넌트 하위에 D가 있다. 이때 App이라는 컴포넌트에서 선언한 text 변수의 값인 'jenny'를 가장 하위 컴포넌트인 C와 D에서 사용하려고 한다.

 

App 컴포넌트에서 선언한 text 변수의 값을 A와 B의 name이라는 속성의 속성값으로 지정한다. 이후 A, B를 선언한 곳에서는 this.props.name이 'jenny'이다. 구조 분해 할당으로 name 변수를 선언하고, 그 변수의 값을 value라는 속성의 속성값으로 둔다.

 

이제 C와 D를 선언한 곳에서는 this.props.value가 'jenny'이다. 구조 분해 할당으로 value라는 변수를 선언하고, return 값에서 <div> 태그 안에 넣어주면 value의 값인 'jenny'가 잘 담겨서 브라우저에 렌더링 된다.

 

[그림 4] 브라우저에 나타난 Elements

id가 root인 <div> 태그 하위에 2개의 <div> 태그가 있고, 각각 jenny라는 내용을 포함하고 있다.

 

[그림 5] 브라우저에 보여지는 모습

<div> 태그는 block 속성을 갖고 있기 때문에 jenny라는 글자가 각각 다른 행으로 나타나고 있다.

 

 

2. state

state는 상태라는 뜻을 가지고 있는데, 그 의미 그대로 생각하면 된다.

 

얼음에 열을 가하면 고체 상태에서 액체 상태가 되고, 열을 더 가하면 기체 상태로 바뀐다. React에서도 사용자와의 상호작용 과정에서 상태가 계속 변화한다.

 

원래 상태가 언제 어떻게 바뀌었는지 그 변화를 인식할 수 있게 하는 것이 바로 state이다.

 

상태가 변화하는 것의 예시로 로그인, 로그아웃 버튼이 있다. 즉, 어떤 페이지에서 로그인을 했을 때에는 로그아웃 버튼이 나타나고, 로그인을 하지 않은 상태에서는 로그인 버튼이 나타나게 하는 경우이다.

 

아래의 코드 예시를 통해 알아보겠다.

<div id="root"></div>
<script type="text/babel">
    class Login extends React.Component{
        state = {
            isLogin:false
        };
        render() {
            const obj = {
                ...this.state,
                isLogin:!this.state.isLogin
            };
            return(<button onClick={() => {this.setState(obj)}}>
                        {this.state.isLogin ? 'Logout' : 'Login'}
                    </button>)
        }
    };
    class App extends React.Component{
        render() {
            return(<Login/>)
        }
    };
    ReactDOM.render(
        <App/>,
        document.querySelector('#root')
    );
</script>

Login 컴포넌트를 선언하는 곳에 state = { isLogin: false }; 라는 부분이 있다. state는 React에서 이미 지정한 변수이기 때문에 let이나 const로 선언할 필요가 없다. 또한, state 변수의 데이터타입은 object이다.

 

Login 컴포넌트의 return 값을 보면, <button> 태그에 onClick 함수가 있다. 해당 버튼을 클릭했을 때 setState(obj)라는 함수가 실행된다. obj 변수는 현재 isLogin 속성의 속성 값이 false라면 true로 바뀌고, true라면 false로 바뀐다.

 

삼항 연산자 ( ? A : B)로 작성된 부분을 해석하면 버튼을 클릭했을 때 isLogin 속성의 속성 값이 true면 버튼 이름이 Logout으로 바뀌고, 그 반대의 경우에는 버튼 이름이 Login으로 바뀐다.

 

React를 배우기 전에는 Node.js에서 로그인이 되어 있는 경우와 그렇지 않은 경우를 각각  <template> 태그 안에 담아서 addEventListener로 클릭했을 때 마다 서로 다른 <template> 태그가 상위 태그의 innerHTML이 되도록 해주었다. 이제 React의 편리함을 점점 깨닫고 있는 것 같다.

 

state에 대한 다른 예시를 하나 더 살펴보겠다.

<div id="root"></div>
<script type="text/babel">
    class Counter extends React.Component{
        state = {
            number:0
        };
        incre = (index) => {
            const increase = {
                ...this.state,
                number:this.state.number + index
            };
            this.setState(increase);
        }
        decre = (index) => {
            const decrease = {
                ...this.state,
                number:this.state.number - index
            };
            this.setState(decrease);
        }
        render() {
            return(<div>
                        <h3>{this.state.number}</h3>
                        <button onClick={() => this.incre(2)}>+</button>
                        <button onClick={() => this.decre(2)}>-</button>
                </div>)
        }
    };
    class App extends React.Component{
        render() {
            return(<div><Counter/></div>)
        }
    };
    ReactDOM.render(
        <App/>,
        document.querySelector('#root')
    );
</script>

App 컴포넌트 안에 Counter라는 컴포넌트가 있다. Counter 컴포넌트에는 현재 상태에 대한 숫자와, (+) 버튼, (-) 버튼이 각각 1개씩 있다. (+) 버튼을 클릭했을 때에는 숫자가 2씩 증가하고, (-) 버튼을 클릭했을 때에는 숫자가 2씩 감소하도록 나타내고자 한다.

 

Counter 컴포넌트가 선언된 곳의 state에 number:0 이므로 브라우저에 처음 렌더링 되었을 때 숫자는 0으로 나타난다. incre와 decre라는 함수는 index라는 인자값 만큼 state의 number 속성의 속성 값을 증가시키거나 감소시킨다.

 

버튼을 클릭할 때 incre와 decre 함수가 실행되어 state가 바뀌게 되고, 이에 따라 <h3> 태그 안에 들어가는 값인 this.state.number도 계속 바뀌어서 브라우저에 나타난다. 

'React' 카테고리의 다른 글

[React] css 적용하기  (0) 2022.04.20
[React] 구구단 게임  (0) 2022.04.20
webpack 소개 및 사용 방법  (0) 2022.04.20
[React] 틱택토 게임 구현  (0) 2022.04.17
React 소개  (0) 2022.04.12
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/09   »
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
글 보관함