티스토리 뷰

발생일: 2016.12.13

키워드: React, setState, 리액트, setState not working

문제:
setState()로 상태를 변경하려는데, 변경한 상태 값이 적용되지 않는다.

대략 아래와 같은 코드의 컴포넌트이고,

{
    ...
    getInitialState() {
        return {
            foo: 'foo',
            bar: 'bar'
        };
    },
    makeFooUppercase() {
        var state = this.state;
        state.foo = 'FOO';
        this.setState(state);
    },
    makeBarUppercase() {
        var state = this.state;
        state.bar = 'BAR';
        this.setState(state);
    },
    makeUppercase() {
        this.makeFooUppercase()
        this.makeBarUppercase();
    },
    ...
}

makeUppercase() 를 실행해보았더니 결과는

{ foo: 'FOO', bar: 'BAR' } 를 의도했지만,
{ foo: 'foo', bar: 'BAR' } 와 같이 출력된다.

왜일까?


해결책:

React 문서에 따르면 setState()는 동기로 실행되는 것이 보장되지 않는다고 한다.
정확한 동작 방식은 모르겠지만, 언뜻 코드를 살펴보니 성능을 위해 변경되는 상태를 큐에 넣어두었다가 묶어서 실행하는 것 같다.

위에서 발생했던 문제는 상태가 변경되기 전에 기존 상태 값으로 다시 업데이트했기 때문이었다.
makeFooUppercase()와 makeBarUppercase()에서 기존 상태 객체를 이용해 전체 상태를 설정하는 부분이다.

기존 상태 객체를 이용했던 건 한꺼번에 여러 상태를 변경할 때 간결하게 작성할 목적이었다. 하지만, 이렇게 setState()가 연속으로 호출되는 경우도 있으니 필요한 상태만 골라 적용하는 게 좋겠다.

아래처럼 코드를 수정하는 걸로 해결했다.

{
    ...
    makeFooUppercase() {
        this.setState({
            foo: 'FOO'
        });
    },
    makeBarUppercase() {
        this.setState({
            bar: 'BAR'
        });
    },
    ...
}








반응형
댓글
공지사항