[React] State가 무엇일까?

김유진·2022년 10월 5일
0

React

목록 보기
39/64

리액트에서의 state는 컴포넌트 내부에서 바뀔 수 있는 값이다.
전에 살펴보았던 props는 부모 요소에서 설정하기 때문에 읽기 전용만 되었는데, state는 이 친구와 다른 성질을 가지고 있다고 말할 수 있다. :)
전달받은 값을 state를 이용하여 어떻게 바꿀 수 있을까?

1. 클래스형 컴포넌트의 state

constructor(props) {
	super(props); //state의 초기값 설정하기
    this.state = {
      number : 0
    };
}

먼저 state의 초기값을 지정해보자. 우리는 이를 위해서 사용해야 하는 것이 바로 constructor라는 컴포넌트의 생성자 메서드이다. (그냥 암기하삼) constructor을 작성할 때에는 반드시 super(props)를 호출해 주어야 한다.
super 함수가 호출되면, 현재 클래스형 컴포넌트가 상속받고 있는 리액트의 Component 클래스가 지닌 생성자 함수를 호출해 준다. 그리고 this.state에 초기값을 설정해 주어용.

render() {
  const {number} = this.state;
  return (
    <div>
    	<h1>number</h1>
    	<button onClick = {() => { this.setState({number : number + 1 }); }}
		//this.setState를 사용하여 state에 새로운 값을 집어넣습니다. 
    </div>
    );
}

위와 같이 사용 가능하다.
여러가지 state를 사용한다면 여러가지 state 그냥 골라서 쓰면 된다.

constructor 이용하고 싶지 않아요..

그럼 아래와 같이 작성 가능합니당

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

이렇게 써도 된다. 메서드를 복잡하게 안써도 된다!

this.setState에 객체 대신에, 함수 인자 전달해보기!

위에서 작성하였던 코드는 setState에 함수를 전달하였다.
우리가 this.setState를 사용하여 state 값을 업데이트하면 상태가 비동기적으로 업데이트됩니다.
아래 코드 예시를 볼까용

onClick = {() => {
 this.setState({number : number + 1 });
 this.setState({number : this.state.number + 1 });
}

코드를 위와 같이 작성하게 되면, this.setState를 두 번 사용하는데도, 1밖에 숫자가 더해지지 않는다. 그 이유는 , this.setState 를 사용한다고 해서 state의 값이 바로 바뀌지 않기 때문입니다!

그래서 옛날에 콘솔창에 찍어볼 때 고생 많이 했지.. 왜 한번에 바뀌지 않느냐며..ㅠㅠ
이를 해결하기 위해서는 this.setState를 사용할 때, 객체 대신에 함수를 인자로 넣어주는 것이다.

this.setState((prevState, props) => {
  return {
    //업뎃하고 싶은 내용
  }
})

여기서 prevState는 기존 상태이고, props는 현재 지내고 있는 props를 가리킵니다. 만약 props가 필요하지 않는다면 생략해도 된다.

this.setState((prevState => {
  return {
    number : prevState.number + 1
  };
});

이렇게 preState를 사용하여 작성해도 되고,

this.setState((prevState => ({
  return {
    number : prevState.number + 1
  };
}));

이렇게 객체를 바로 반환해도 된다!

this.setState 끝나고 바로 일시키고 싶은데..

setState함수의 두번째 파라미터로 콜백함수를 받을 수 있다.

onClick = {() => {
  this.setState({number : number + 1 }, () => {console.log('방금 setState 수행완료함'); console.log(this.state);});
}}

2. 함수형 컴포넌트의 state

배열 비구조화 할당하기

배열 비구조화 할당이 무엇일까?

배열 안에 있는 값을 쉽게 추출할 수 있도록 해 주는 문법

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

이에 대하여 배열 비구조화 할당을 이용해보자.

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

훨씬 간단하게 사용 가능하다. 객체랑 비교해서 다시 복습하고 잘 써먹을 수 있도록 하자

useState 사용하기

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. state를 사용할 때 가장 많이 실수하는 부분

state의 값을 바꾸고 싶다고 아래와 같이 쓴 경험이 많다.

  • 클래스형 컴포넌트에서
this.state.number = this.state.number + 1;
this.state.array = this.array.push(2);
this.state.object.value = 5;
  • 함수형 컴포넌트에서
const [object, setObject] = useState({a : 1, b: 1});
object.b = 2;

값을 업데이트 할 때에는 꼭 배열이나 객체 사본을 만들고, 그 사본에 값을 업데이트해주세요 그리고 그 사본의 상태를 새터 함수를 통하여 업데이트해주세요

아래 예시를 통하여 확인해봅시다~

  • 객체를 다룰 때
const object = { a : 1, b : 2, c : 3 };
const nextObject = { ...object, b : 2 }; //사본을 만들고, b 값만 덮어쓰기!
  • 배열을 다룰 때
const array = [
  {id : 1, value : true },
  {id : 2, value : true },
  {id : 3, value : false},
  ];
let nextArray = array.concat({id : 4}); //새 항목 추가! 
nextArray.filter(item => item.id !==2); //id가 2인 항목 제거
nextArray.map(item => (item.id === 1 ? {...item, value : false } : item)); //id 1인거 false

1개의 댓글

comment-user-thumbnail
2022년 10월 18일

글 잘 읽고가요!

답글 달기