3.4 state

  • state: 컴포넌트 내부에서 바뀔 수 있는 값
  • props: 컴포넌트가 사용되는 과정에서 부모 컴포넌트가 설정하는 값(읽기전용)

props를 바꾸려면 부모에서 바꿔줘야한다. (부모에서 물려받는 속성이기 때문이다!)

App 컴포넌트에서 MyComponent를 사용할 때 props를 바꿔야 값이 변경되지만 전달받은 name 값을 직접 바꿀 수 없다.

state는 class에서 state가 있고, 함수형에서는 useState라는 함수로 사용한다.

3.4.1 클래스형 컴포넌트의 state

//Counter.js 

import React, {Component} from 'react';

    class Counter extends Component {
        constructor(props) {
            super(props); -> state의 초기값 설정
            this.state = {
                number:0
            };
        }

        render() {
            const{ number } = this.state; 
	   //state를 조회할 때 this.state로

            return(
                <div>
                    <h1>{number}</h1>
                    <button 
                        onClick = {() => {
                            this.setState({ number: number + 1 });
			   //this.setState를 사용해 새로운 값을 넣을 수 있다
                        }}> +1 </button>
                </div>
            )
        }


    }

export default Counter;

💡 컴포넌트 state

컴포넌트 state를 설정할 때는 constructor 메서드를 작성해 설정 해야한다.

constructor(props) {
  super(props);
    this.state = {
      number:0
    };
  }

이 constructor는 컴포넌트의 생성자 메서드이며 constructor를 작성할 때는 super(props)를 꼭 호출해야하고 이 함수가 호출되면 현재 상속받고 있는 리액트의 Component 클래스가 지닌 생성자 함수를 호출해 준다.

그 다음은 this.state 값에 초깃값을 설정해준다.(state는 객체 형식이여야한다.)

💡 render

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

render 함수에 현재 state를 조회할 때는 this.state를 조회하면된다. button은 onClick이라는 값을 props로 넣어 줬고, 이것은 버튼이 클릭될 때 호출시킬 함수를 설정할 수 있게 해준다 (= '이벤트를 설정한다' 라고 부른다.)

이벤트 함수를 넣어 줄 때는 화살표 함수 문법(=arrow function)을 사용해 넣어주고, 함수 내부에는 this.setState라는 함수를 사용했다. 이 함수가 state 값을 바꾸게 해주는 것이라 생각하면 된다.


(버튼을 클릭하면 숫자가 올라간다.)

3.4.1.1 state 객체 안에 여러 값이 있을 때

Counter.js

class Counter extends Component {
        constructor(props) {
            super(props);
            this.state = {
                number:0,
                fixedNumber: 0
            };
        }

        render() {
            const{ number, fixedNumber } = this.state;

            return(
                <div>
                    <h1>{number}</h1>
                    <h2>안바뀌는거: {fixedNumber}</h2>
                    <button 
                        onClick = {() => {
                          this.setState({ number: number + 1 });
                        }}> +1 </button>
                </div>
            )
        }
    }

현재 state 안에 fixedNumber라는 값을 추가했고, 버튼이 클릭될 때 fixedNumber 값은 두고 number만 바꿀것이고, this.setState 함수를 사용할 때 인자로 전달되는 개체 내부에 fixedNumbe를 넣어 주지 않았다.

💡 this.setState 함수는 인자로 전달된 객체 안에 들어 있는 값만 바꾸어준다.

3.4.1.2 state를 constructor에서 꺼내기

state를 constructor 말고 다른 방식으로 초깃값을 설정할땐 static을 사용하면 된다.

state = {
     number: 0,
     fixedNumber: 0
  };

이제 뒤에 나오는 내용들은 constructor 대신 state를 쓰니 참고하자

3.4.1.3 this.setState에 객체 대신 함수 인자 전달하기

render() {
            const{ number, fixedNumber } = this.state;
            return(
                <div>
                    <h1>{number}</h1>
                    <h2>안바뀌는거: {fixedNumber}</h2>
                    <button 
                        onClick = {() => {
                           this.setState(prevState => {
                               return{
                                   number: prevState.number +1
                               }
                           })
 			// 위 아래는 똑같은 기능이고, 아래는 함수에서 바로 객체를 반환한다는 의미이다.
                           this.setState(prevState=>({
                               number: prevState.number +1
                           }))

                        }}> +1 </button>
                </div>
            )
        }

여기서 prevState는 기존 상태고 props는 현재 지니고 있는 props를 가르킨다. 업데이트 과정에서 props가 안 필요하면 생략해도 된다.

//화살표 함수에서 값을 바로 반환하고 싶다면 {} 를 생략해도 된다.
const sum = (a, b) => a + b;

onClick에서 두 번째로 this.setState 함수를 사용할 때는 화살표 함수에서 바로 객체를 반환하도록 했기 때문에 prevState ⇒ ({})와 같은 형태로 코드가 이루어 진다.

3.4.1.4 this.setState가 끝난 후 특정 작업 실행하기

setState를 사용해 값을 업데이트하고 그 다음 특정 작업을 하고 싶을때 setState의 두 번째 파라미터로 callback 함수를 등록 해 작업을 처리할 수 있다.

<button 
        onClick = {() => {
            this.setState({
                number: number +1
            },
            ()=> {
                console.log('방금 setState가 호출되었습니다.');
                console.log(this.state);
            }
        )
            
        }}> +1 </button>

3.4.2 함수형 컴포넌트에서 useState 사용하기

16.8 버전부터 useState라는 함수를 사용해 함수형 컴포넌트에서도 state를 사용할 수 있게 되었고, 이 과정에서 Hooks을 사용하게 된다.

3.4.2.1 배열 비구조화

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

//비구조화 할당 후
const array= [1, 2];
const [one, two] = array;

3.4.2.2 useState 사용하기

//Say.js

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;

useState 함수 인자에는 상태 초깃값을 넣는다 useState는 객체가 아니여도 되고, 값의 형태는 자유이며 숫자/문자/객체/배열 다 가능하다.

함수를 호출하면 배열이 반환되는데 배열의 첫 번째 원소는 현재 상태, 두 번째 원소는 상태를 바꾸어주는 함수이다. 이 함수를 세터(Setter) 함수라고 부른다.

(배열 비구조화 할당을 통해 이름을 자유롭게 정해 줄 수도 있다.)

3.4.2.3 한 컴포넌트에서 useState 여러 번 사용하기

//Say.js

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={{color}}>{message}</h1>

            <button style={{color:'red'}} onClick={()=> setColor('red')}>빨간색</button>
            <button style={{color:'green'}} onClick={()=> setColor('green')}>초록색</button>
            <button style={{color:'blue'}} onClick={()=> setColor('blue')}>파란색</button>
            
        </div>
    )
}

export default Say;

좋은 웹페이지 즐겨찾기