본문 바로가기

# Tech/React

[Typescript React] 상태 관리 라이브러리


깊숙한 곳에 숨겨진 함정


클래스 컴포넌트에 있는 setState 메소드는 주의해야 할 특징을 가지고 있습니다.

쉽게 설명하자면 병렬로 처리하지만, 여러개가 묶일 때 까지 미룬다. 입니다.

  • 비동기로 작동한다.  (=상태가 즉시 변경되지 않는다.)
  • 최적화를 위해 여러 setState를 묶어서 처리할 수 있다. 



아래의 카운터 컴포넌트를 살펴볼까요?

interface Props {
    delta: number;
}

interface State {
    count: number;
}

class Counter extends React.Component<Props, State> {
    private intervalID: any;
    constructor(props: Props) {
        super(props);
        this.state = {
            count: props.delta
        };
    }

    componentDidMount() {
        this.intervalID = setInterval(this.tick.bind(this), 1000);
    }

    componentWillUnmount() {
        clearInterval(this.intervalID);
    }

    tick() {
        // Wrong!
        this.setState({
            count: this.state.count + this.props.delta
        });
    }

    render(): ReactNode {
        return <h1>{this.state.count}</h1>;
    }
}


위 컴포넌트의 어떤 tick은 실패할 수 있습니다.

상태가 비동기로 변경되기 때문에 this.state와 this.props가 정확하지 않을 수 있기 때문이죠.


여러 setState가 묶일 때 까지 상태의 변경을 미루기 때문에,

2개 이상의 tick이 같은 this.state, this.props를 읽기 때문입니다.


따라서, prevState와 currentProps를 인자로 받는. 

2개를 인자로 받는 setState 형식을 사용해야 합니다.

tick() {
    // OK.
    this.setState((prevState, currentProps) => {
        count: prevState.count + currentProps.delta;
    });
}





상태 관리 라이브러리의 필요성


위의 이슈는 리액트의 특징으로 발생한 문제이며 변경되지 않을겁니다.

좀 더 깊숙하고, 좀 더 관리하기 어려운 이슈들도 남아있죠.


상태 관리 라이브러리는 이러한 리액트의 이슈를 방지해줍니다.

대표적인 라이브러리는 다음과 같습니다.

  • Redux
  • Mobx


이에 대한 사용법은 차후에 다루도록 하겠습니다.





하지만 한 번만 더 생각해보세요


상태 관리 라이브러리는 확실히 좋은 기능입니다.

어플리케이션의 상태의 규모가 커진다면, 관리하기 어려워지거든요.


하지만 상태 관리 라이브러리가 항상 장점만 주는것은 아닙니다.

상태를 효율적으로 관리하기 위해 강한 제약사항을 걸기 때문입니다. 


리액트의 setState의 동작 방식을 이해하고,

이것만으로 상태를 잘 다룰 수 있다고 판단되면,

상태 관리 라이브러리를 도입하는 것은 족쇄로 작용할 수 있습니다.





참고 문헌

React.setState를 사용하지 않는 3가지 이유

당신에게 Redux는 필요 없을지도 모릅니다