[React] state와 setState()

권준혁·2020년 11월 1일
2

React

목록 보기
5/20
post-thumbnail

안녕하세요!
오늘은 state와 setState에 대해서 알아보겠습니다.

리액트의 강점 중 하나는 컴포넌트의 UI데이터가 변경될 때마다 자동으로 다시 render하는 것 입니다.
컴포넌트의 UI데이터가 state이고, 컴포넌트는 state가 변경되면 다시 render합니다.
그래서 항상 최신데이터를 웹을 방문하는 사용자에게 보여 줄 수 있습니다.


그러면 create-react-app을 이용해 프로젝트를 생성 후 컴포넌트를 만들어보겠습니다.
클릭 시 상태값이 증가하고 화면에 상태값이 출력됩니다.

// MyComponent.js
import React from 'react'

export default class MyComponent extends React.Component {
    state = {
        count : 0
    }
    handleOnClick = () => {
        const {count} = this.state
        this.setState({count:count+1})
    }
    render () {
        const {count} = this.state
        return (
            <div>
                <h3>{`COUNT : ${count}`}</h3>
                <div style={{width:'100px', height:'100px', backgroundColor:'black'}} onClick={this.handleOnClick}>
                <h3 style={{color:'white'}}></h3>
                </div>
            </div>
        )
    }
}

App.js에 컴포넌트를 추가합니다.

상태값으로 count가 있고 검은색박스를 클릭할 때마다 상태값이 +1씩 변경됩니다. 상태값이 변경되면 컴포넌트를 다시 그립니다.

클릭 시마다 COUNT가 1씩 증가합니다.


handleOnClick메서드를 수정해보겠습니다.
잘못된 예입니다.

handleOnClick = () => {
  const {count} = this.state
  this.setState({count:count+1})
  this.setState({count:count+1})
}

비동기적 실행

이렇게 작성해도 count는 1씩만 증가합니다.
setState메서드가 비동기로 동작하기 때문입니다.
리액트는 여러개의 setState메서드를 Batch로, 즉, 일괄적으로 처리합니다.
만약 setState메서드가 동기적으로 처리된다면 하나의 setState를 만날 때마다 다시 그리기 때문에 성능이슈가 발생할 수 있습니다.

setState의 함수인수

setState메서드의 인수에 함수를 입력할 수 있습니다.
handleOnClick을 수정하겠습니다.

handleOnClick = () => {
  this.setState(prevState => ({count : prevState.count + 1}))
  this.setState(prevState => ({count : prevState.count + 1}))
}

이제 클릭하면 2씩 증가됩니다.
setState에 입력된 함수는 자신이 호출되기 직전의 상태값을 인수로 받습니다. 따라서 첫 번째 setState가 변경한 상태값이 두 번째 setState의 인수로 들어갔습니다. setState는 비동기적으로 처리되지만 순서가 보장됩니다.


또 다른 잘못된 예입니다.
결론부터 밝히면 setState에서 객체형으로 인수를 넣어, state,props를 두 개 이상 사용할 경우 함수형으로 사용해야 한다는 것입니다.

// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});

this.props와 this.state가 비동기적으로 업데이트될 수 있기 때문에 이런 코드도 지양해야 합니다.
이 코드 또한 함수형으로 바꿀 수 있습니다.

// Correct
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));

setState에서 함수에 전달되는 두 번째 인수는 업데이트가 적용된 시점의 props가 옵니다.


setState의 callback

setState에서 콜백을 사용할 수 있습니다.
handleOnClick을 수정하겠습니다.

handleOnClick = () => {
  this.setState(prevState => ({count : prevState.count + 1}),()=>{
    console.log(`state가 변경됨 : ${this.state.count}`)
  })
}

state가 변경된 후에 로그가 출력됩니다.

이상으로 간단하게 클래스형 컴포넌트의 state와 setState에 대해 알아봤습니다.
함수형 컴포넌트에서 사용하는 Hook등에 관련해서는 나중에 따로 포스팅해볼게요
읽어주셔서 감사합니다

profile
웹 프론트엔드, RN앱 개발자입니다.

0개의 댓글