Back

비동기로 동작하는 react setState

수많은 텍스트박스들의 상태값들을 관리하기 위해 useState를 통해 관리되는 하나의 object 안에 모든 정보를 담아서 사용했었다.

이전에 작성했던 코드에서는 이 상태값을 setState를 통해 한번만 변경시키느라 문제가 없었으나, 이를 직전의 상태를 참조하는 형태로 두 번 변경시키려고 하니 문제가 생겼다.

setState가 이전에 상태를 참조하여 새롭게 덮어씌워지는 구조였었다. 그런데 생각했던 방식대로 진행이 되지 않았고, 디버깅을 했다.

확인을 해보니 setState이후 state값을 확인하니 변경이 바로 이루어지지 않았다.

그상태로 두 번째로 실행하는 setState에서 현재 상태를 참조하여 변경을 하는데, 처음에 실행했던 setState가 반영이 되지 않아 원하는 결과값이 나오지 않게 되었다.

검색을 해보니 애초에 setState는 비동기로 처리된다고 한다.

const [state, setState] = useState({});

const somethingFunc = () => {
  setState({ ...state, a: 1 });
};

const somethingFunc2 = () => {
  setState({ ...state, b: 1 });
};

somethingFunc();
somethingFunc2();
console.log(state); // { b : 1 }

방법을 찾아봤다.

React의 setState에 await을 붙이면?

updateState = () => {
  return new Promise((resolve, reject) => {
    this.setState(
      {
        count: this.state.count - 1,
      },
      () => {
        resolve('updated');
      }
    );
  });
};

decrease = async () => {
  await this.updateState();
  await this.updateState();
  await this.updateState();
};

여기 적혀있는 것을 보면 class component를 사용할때 setState 앞에 await을 붙이면 뭔가 된다고 하는데

useState hooks를 사용하려면 다른 방법이 필요하다고 한다.

그 다른 방법이라는 것을 찾아보려다가 문득 생각이 들었다.

아니 그냥 미리 setState 할 object를 조합하고 있다가 막판에 딱 한번만 하면 되지 않는가?

그렇게 했고 잘 동작한다.

겪어보니 이런 일을 경험할 확률은 아주 높고, 기초중에 기초같은데, 한 번 겪어보니 다음에는 이런식으로 코드작성을 다 해놓고 나중에 다 뜯어고치는 짓을 하지는 않을 것 같다.