Posts [React] React의 state 설정하기
Post
Cancel

[React] React의 state 설정하기


React의 state 설정하기


🔍 state란?

컴포넌트 내부에서 변경될 수 있는 값. props는 부모 컴포넌트가 설정하고, 컴포넌트 자신은 props를 바꾸지 못하는 특성이 있는 것과는 차이가 있다.

리액트에 존재하는 state의 종류는 2가지입니다.

  • 클래스형 컴포넌트가 가지고 있는 state
  • 함수형 컴포넌트가 useState라는 함수로 사용하는 state

🔑 컴포넌트 내부에서 변경하고 싶은 값이 있을 때, state를 활용하면 됩니다.


🔍 클래스형 컴포넌트의 state

새로운 Counter.js 파일을 생성하고 코드를 작성해 주었습니다.

state의 이름과 초기값을 constructor(생성자)에서 설정해 주고, render() 함수에서 this.setState 함수를 통해 state를 변경해 줄 수 있습니다.

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
import React, {Component} from 'react';

class Counter extends Component{

    constructor(props){
        super(props); // constructor 정의 시 반드시 필요!
        this.state = { // state의 초기값 설정 부분
            number:0
        };
    }

    render(){

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

export default Counter;

브라우저에서 버튼을 누를 때마다, 숫자가 1씩 증가함을 확인할 수 있습니다. number 라는 state가, button의 onClick 이벤트에 설정된 함수 내의 this.setState 함수가 +1씩 state를 바꾸고 있는 것입니다. this.setState 함수에서 number+1 이라고 정의해 둔 부분 때문에 작동할 수 있습니다.


✏️ 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
import React, {Component} from 'react';

class Counter extends Component{
    
    state = {
        number: 0
    }

    render(){

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

export default Counter;

✏️ this.setState 함수 사용 시, 인자로 객체 대신 함수를 넘겨줄 수도 있습니다.

1
2
3
4
5
6
7
8
9
...
<button
    onClick={()=> {
        this.setState(prevState =>{
            return{
                number:prevState.number + 1
            };
        });
        ...

✏️ setState로 state의 값을 변경한 다음, 다른 특정한 작업을 하고자 할 때에는 setState의 두 번째 파라미터에 콜백 함수(callback function)를 등록하면 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
...
<button
    onClick={()=> {
        this.setState(
            {
                number : number+1
            },
            ()=>{
                console.log('setState의 호출 이후');
                console.log(this.state);
            });
        ...

this.setState 함수의 첫 번째 파라미터에는 state 값을 변경하는 코드를 넣었고, 두 번째 파라미터에는 화살표 함수 문법을 사용하여 콜백 함수를 지정한 모습입니다. 마우스로 버튼을 누를 때마다, 개발자 도구의 콘솔란에 출력이 될 것입니다.


지금까지 살펴본 코드는 클래스형 컴포넌트에서 state를 사용하는 모습들이었습니다.

원래 함수형 컴포넌트의 경우 state를 사용할 수 없었으나, 리액트 16.8 버전 이후에는 useState 함수를 사용하여 함수형 컴포넌트에서도 state를 사용할 수 있습니다. 이전 게시물에서 언급한 Hooks라는 것을 사용하게 됩니다.


🔍 배열 비구조화 할당하기

이전에 객체 비구조화 할당 에 대하여 언급한 적이 있습니다. 예를 들어, props 의 값들을 쉽게 가져오기 위해 const { name, children } = props 와 같이 코딩하는 것을 말합니다.

배열 비구조화 할당도 이와 유사합니다.

1
2
const array = [1, 2]
const [one, two] = array

one 에는 array[0] 값이, two 에는 array[1] 값이 추출되어 손쉽게 들어가게 됩니다.

이와 같은 방식이 함수형 컴포넌트의 useState 함수에서 그대로 적용됩니다!


🔍 함수형 컴포넌트의 state - useState의 사용

함수형 컴포넌트에서 state를 사용하는 방법을 알아보겠습니다. 먼저, import 문에 다음과 같이 useState를 불러와야 가능합니다.

1
import React, { useState } from 'react'

클래스형 컴포넌트에서는 state = { } 값을 정하고, this.setState 함수로 state의 값을 변경하는 방식이었습니다.

함수형 컴포넌트에서는 useState 함수가 이 두 개의 역할을 같이 할 수 있게 해 주는데 방식이 살짝 다릅니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import React, {useState} from 'react';

const Say = () => {
    const [message, setMessage] = useState('초기값');
    const onClickEnter = () => setMessage('안녕!');
    const onClickLeave = () => setMessage('잘가!');
    return (
        <div>
            <button onClick={onClickEnter}>입장</button>
            <button onClick={onClickLeave}>퇴장</button>
            <h1>{message}</h1>
        </div>
    );
};

export default Say;
1
const [message, setMessage] = useState('초기값');

배열 비구조화 할당 문법으로 이해하면, useState 함수를 호출할 시 배열이 반환되며, 배열의 첫 번째 원소는 현재 상태, 두 번째 원소는 상태를 바꾸어 주는 함수가 됩니다. 그것이 각각 message와 setMessage에 들어가는 것입니다.

즉, message는 현재 state의 상태가 저장되고, setMessage 는 state를 바꾸어 주는 setter 함수가 됩니다.

위처럼 코드를 작성할 경우 message 에는 ‘초기값’이라는 문자열이 들어갈 것이며, setMessage는 그러한 state의 값을 변경하는 함수가 됩니다.

(🔑 message, setMesage 등의 이름은 사용자 마음대로 정하면 되는 것입니다.)

1
2
const onClickEnter = () => setMessage('안녕!');
const onClickLeave = () => setMessage('잘가!');

그리고 이것은 버튼 onClick 함수를 사전에 정의해 놓은 부분입니다. 화살표 함수 문법과 setMessage 함수를 사용하여 작성한 모습입니다.

아래에 return 문에서 버튼 각각에 onClick 함수를 지정해 줍니다.

버튼을 누를 때마다, message에 있는 값이 안녕! 혹은 잘가!로 바뀔 것입니다.


useState 함수는 하나의 컴포넌트 안에서 여러 번 사용해도 상관이 없습니다. message라는 상태 외에도 다른 상태를 더 추가하여 관리할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import React, {useState} from 'react';

const Say = () => {
    const [message, setMessage] = useState('초기값');
    const onClickEnter = () => setMessage('안녕!');
    const onClickLeave = () => setMessage('잘가!');

    const [color, setColor] = useState('black');

    return (
        <div>
            <button onClick={onClickEnter}>입장</button>
            <button onClick={onClickLeave}>퇴장</button>
            <h1 style=>{message}</h1>
            <button style= onClick={()=>setColor('red')}>RED</button>
        </div>
    );
};

export default Say;

새로운 state인 color를 관리하고, h1 태그의 텍스트 색깔을 버튼을 눌러 변경하는 기능을 추가합니다.

h1의 style에는 color state 값이 들어가게 되고, 버튼의 onClick 부분에 setColor 함수를 등록하여 state를 바꿀 수 있도록 합니다.


📝 state의 값을 변경할 때에는, 클래스형 컴포넌트일 경우 this.setState 함수를, 함수형 컴포넌트일 경우 useState 함수만을 사용하는 것이 포인트입니다.


🔑 props와 state의 차이

  • props와 state 모두 컴포넌트에서 사용 혹은 렌더링할 데이터를 담고 있다.
  • props는 부모 컴포넌트 쪽에서 설정해 주는 것이다. 컴포넌트 자신이 변경할 수 없다.
  • 반면 state는 컴포넌트 자신이 직접 가지고 있는 값이고, 그 값의 변경도 내부에서 가능하다.

이 포스팅은 리액트를 다루는 기술(저자 김민준)을 학습하는 과정에서 개인적으로 정리한 내용입니다.