본문 바로가기

Front/React

Mobx Store 내부 변수 실시간 tracking 안되는 이슈

팀원 코드리뷰중 확인한 이슈다.

아래와 같은 상황이 있다고 하자

 

분명 코드상으로는 문제가 없어보이지만,

Store에서 서버로 데이터 요청해서 받아온 정보가 제대로 세팅되지 않고

기존에 task 선언할때 세팅되었던 정보로 세팅된다.

function TaskModifyContainer() {
    const { taskStore } = useStore();
    .
    .
    .
    const { task } = taskStore;
    .
    .
    .
    const initTaskModify = async () => {
        try {
            await taskStore.getTask(taskId);
              taskStore.setTask({
                ...task, //6번 라인에서 로드한 정보로 세팅된다.
                startDate: task.startDate?.substr(0, 8),
                endDate: task.endDate?.substr(0, 8),
              });
        }
        .
        .
        .
    };
    .
    .
    .
}

여기서 가장 간단히 해결하는 방법은 taskStore.task로 부르는 것이다.

function TaskModifyContainer() {
    const { taskStore } = useStore();
    .
    .
    .
    const { task } = taskStore;
    .
    .
    .
    const initTaskModify = async () => {
        try {
            await taskStore.getTask(taskId);
              taskStore.setTask({
                ...taskStore.task, //6번 라인에서 로드한 정보로 세팅된다.
                startDate: taskStore.task.startDate?.substr(0, 8),
                endDate: taskStore.task.endDate?.substr(0, 8),
              });
        }
        .
        .
        .
    };
    .
    .
    .
}

근데 왜 이런 이슈가 발생했을까?

자바스크립트 엔진의 동작방식을 생각해서 판단해보자..

taskStore.getTask는 API콜이므로 이벤트 스택에 쌓이고, taskStore는 Event Queue에 쌓인다.

반면에 나머지 부분은 Call Stack에 쌓여서 동작하는 부분이다.

즉, const{task} = taskStore;와 taskStore.setTask는  자바스크립트 Call Stack에 쌓인다.

 

때문에 같은 변수지만 싱크가 안맞는 것으로 추측된다.

보통 API 콜에 await를 사용하면 일반적으로 API 콜하는 것과 달리 코드가 순차적으로 실행되기 때문에 문제가 없을 것이라고 생각했다. 같은 Store를 사용하더라도 API콜하는 부분은 싱크가 안맞을 수 있다는 사실을 주의해야겠다.

 

즉 정리하면, async, await를 사용하면 코드 실행 순서는 보장되지만, call Stack에 쌓여 수행되는 객체와 await 함수에서 객체의 동기화는 보장할 수 없다.