[리액트] setState 비동기 해결, 콜백함수

[예시 - 결과, 코드]

버튼을 클릭하면 숫자를 1 더하고 빼는 간단한 컴포넌트를 만들었다.

alertNumber()라는 함수를 만들어 현재 숫자가 무엇인지 알려주는 창을 띄어준다.

import React, { Component } from "react";

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

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

export default Counter;

 

 

[실행 결과] 화면에 숫자가 0일때 alert와 console 창에도 0이 뜸 ❓❗

영상을 보면 알겠지만,, 뭔가 이상하다는 걸 눈치챘을 거다

alert, console.log의 값과 화면에 출력되는 값이 싱크가 안 맞는 느낌..!!🙄

 

내가 원하던 결과는 맨 처음에 +1 버튼을 누르면 alert과 console 창에 1이 뜨고, 화면에 1이 뜨는 건데

실행 결과는 alert과 console 창에 0이 뜨고, 화면에 1이 뜨게 된다...

 

이런 상황이 발생하는 이유는 setState의 작동 방식이 비동기적이기 때문이다.

this.setState를 실행하고 바로 console.log와 this.alertNumber()를 수행해도 DOM에 보이는 것보다 한 박자 늦게 숫자가 기록된다.

 

console.log와 this.alertNumber()가 실행되는 건 setState에 의해 state가 변경되기 전이라는 것이다.

 

[해결 방법] 

어디가 달라졌을까요??!

import React, { Component } from "react";

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

  alertNumber() {
    alert(this.state.number);
  }
  render() {
    const { number } = this.state;
    return (
      <div>
        <h1>{number}</h1>
        <button
          onClick={() => {
            this.setState({ number: number + 1 }, () => { //변경된 부분
              console.log(this.state);
              this.alertNumber();
            });
          }}
        >
          +1
        </button>
        <button
          onClick={() => {
            this.setState({ number: number - 1 }, () => { //변경된 부분2
              console.log(this.state);
              this.alertNumber();
            });
          }}
        >
          -1
        </button>
      </div>
    );
  }
}

export default Counter;

정답은 콜백 함수이다.

위에선 this.setState와 console.log, this.alertNumber()의 연결고리를 만들어 주지 않았는데

이번에는 콜백 함수 ( ()=>{} )로 연결고리를 만들어 주었다.

 

즉, setState(state변경, callback) 형식으로 변경해주었다.

 

화면에 숫자가 0일때 alert와 console 창에는 1이 뜸

짜잔✨✨

 

320x100