state


state

state는 props의 내용을 변경할 때 사용됩니다. 앞서 props에 대한 포스트에서 name="관리자"와 같이 전달했었고, 해당 컴포넌트는 이를 받아 화면에 출력하는 용도로 사용했습니다. props를 직접 변경하고자 하는 경우에는 다시 name="변경"과 같이 해야 하는데, 이러한 불편함을 해결하는 것이 state 입니다.

state는 함수형과 클래스형이 있습니다.

클래스형 state

클래스형 state는 class 안에 constructor를 이용하여 상속받은 Component의 생성자를 실행하고, this를 통해 해당 클래스 내에서 사용되는 변수에 접근하게 됩니다.

[Plus.js]

import React, { Component } from  "react";

class Plus extends Component {
    constructor(props) {
        super(props);

        this.state = {
            number: 0
        }
    };

    render() {
        const { number } = this.state;
        return (
            <div>
                <h1>{number}</h1>
                <button onClick={() => { this.setState({ number: number + 10 });}}>+10</button>
            </div>
        );
    };
}

export default Plus;
[App.js]

import React, { Fragment } from 'react';
import Plus from "./Plus";

function App() { // 함수형 컴포넌트
  return (
    
    <Fragment>
      <Plus></Plus>
    </Fragment>
    
  );
}

export default App;

클래스형 state는 setState를 이용해서 해당 변수에 접근이 가능하고 변경할 수 있습니다.

아래 코드처럼, 직접적으로 this.state.number로 값을 변경하면 어떻게 될까요?

[Plus.js]

import React, { Component } from  "react";

class Plus extends Component {
    state = {
        number: 0
    };

    render() {
        const { number } = this.state;
        return (
            <div>
                <h1>{number}</h1>
                <button onClick={() => { this.setState({ number: number + 10 });
                this.setState({number: this.state.number + 5}) }}>+10</button>
            </div>
        );
    };
}

export default Plus;

this.setState가 두 번 사용되면서, 한 번은 +10 씩 또 다른 한번은 +5 씩 총 +15가 되어야 하지만 마지막 +5만 실행됩니다.

this.setState를 사용한다고 해서 바로 바뀌지 않습니다.

위와 같은 현상을 해결하기 위해서는, 인자로 함수를 넣어 주는 방식을 사용합니다.

[Plus.js]

import React, { Component } from  "react";

class Plus extends Component {
    state = {
        number: 0
    };

    render() {
        const { number } = this.state;
        return (
            <div>
                <h1>{number}</h1>
                <button onClick={() => { 
                    this.setState((prevState) => {
                        return {
                            number: prevState.number + 10
                        };
                    });

                    this.setState(prevState => ({
                        number: prevState.number + 5
                    }));
                }}>+10</button>
            </div>
        );
    };
}

export default Plus;

위 코드에서 return을 사용하는 방식과 바로 객체로 반환하는 형식은 모두 같은 동작을 하게 됩니다.

콜백

콜백은 해당 함수가 실행 된 후, 특정 작업을 진행하기 위해 사용됩니다.

위 +10, +5 를 더하는 코드에서 해당 내용이 실행 된 후, console.log()를 이용해 메시지를 출력하는 코드는 아래와 같습니다.

[Plus.js]

import React, { Component } from  "react";

class Plus extends Component {
    state = {
        number: 0
    };

    render() {
        const { number } = this.state;
        return (
            <div>
                <h1>{number}</h1>
                <button onClick={() => { 
                    this.setState((prevState) => {
                        return {
                            number: prevState.number + 10
                        };
                    }, () => {
                        console.log("+10, state 호출.")
                    });

                    this.setState(prevState => ({
                        number: prevState.number + 5
                    }), () => {
                        console.log("+5, state 호출.")
                    });
                }}>+10</button>
            </div>
        );
    };
}

export default Plus;

함수형 state

클래스형에서는 setState를 이용했지만, 함수형에서는 useState를 사용합니다.

[Hello_bye.js]

import React, { useState } from "react";

const Hello_bye = () => {
    const [message, setMessage] = useState();
    const onClickEnter = () => setMessage("안녕하세요.");
    const onClickLeave = () => setMessage("안녕히 가세요.");

    return (
        <div>
            <button onClick={onClickEnter}>입장</button>
            <button onClick={onClickLeave}>퇴장</button>
            <p>{message}</p>
        </div>
    );
};

export default Hello_bye;

App.js에서 Hello_bye 컴포넌트를 추가하고 위 코드를 작성해 실행하면 버튼 클릭 시 해당 메시지가 나타나는 것을 확인할 수 있습니다.

여기서, useState()가 실제 동작하는 방식을 자세히 알기 어렵습니다.

먼저, 버튼 태그에서 onClick이 발생하면 onClickEnter 혹은 onClickLeave 함수가 호출됩니다.

onClickEnter 함수가 호출되면, 상단에 선언된 onClickEnter 화살표 함수가 실행됩니다.

전달되는 인자가 없기 때문에 ()에는 어떤 값도 없고, setMessage()가 실행됩니다.

이때, useState()가 message, setMessage 로 추출이 되는데, setMessage는 함수이고 해당 함수에서 전달된 "안녕하세요" 혹은 "안녕히 가세요."가 message에 전달되게 됩니다.

그후, message의 값이 출력됩니다.

이 정도의 흐름만 이해하시고 넘어가시면 됩니다.




© 2017. by k3y6reak

Powered by k3y6reak