ilokesto

문제 해결

store가 예상과 다르게 동작할 때 이 페이지를 확인하세요.

객체를 바꿨는데 구독자가 실행되지 않습니다

객체를 제자리에서 직접 수정하고 같은 참조를 반환했을 가능성이 큽니다.

store.setState((prev) => {
  prev.count += 1; // 직접 수정 / 제자리 변경
  return prev;
});

참조가 같기 때문에 Object.is(prev, resolvedState)가 true이고 store는 구독자에게 알리지 않습니다. 대신 새 객체를 반환하세요.

store.setState((prev) => ({ ...prev, count: prev.count + 1 }));

필드가 사라졌습니다

setState()는 상태를 교체합니다. merge하지 않으며 deep merge도 절대 수행하지 않습니다.

store.setState({ name: "Ada" });

이전 상태에 theme이 있었다면 그 필드는 사라집니다. 필요한 필드는 명시적으로 보존하세요.

store.setState((prev) => ({ ...prev, name: "Ada" }));

updater가 예상과 다른 값을 봅니다

updater는 최종 적용 단계의 상태를 받습니다. 미들웨어는 그 전에 업데이트를 변환할 수 있습니다. 어떤 미들웨어가 updater를 일찍 계산하면 뒤쪽 미들웨어는 원래 updater가 아니라 값을 받습니다. 미들웨어 순서와 각 미들웨어가 next()로 전달하는지 확인하세요.

owner가 사라졌는데 리스너가 계속 실행됩니다

unsubscribe 호출을 잊은 것입니다.

const unsubscribe = store.subscribe(() => render(store.getState()));

// later
unsubscribe();

구독 해제는 component unmount, widget destroy, route disposal, module shutdown에 연결하세요.

미들웨어 순서가 예상과 다릅니다

pushMiddleware()는 뒤에 추가하고 unshiftMiddleware()는 앞에 추가합니다. chain이 reduceRight로 만들어지기 때문에 배열의 첫 미들웨어가 업데이트를 먼저 받습니다.

순서가 중요하다면 작은 테스트를 쓰거나 next() 앞뒤로 log를 남기세요.

store.pushMiddleware((state, next) => {
  console.log("before A");
  next(state);
  console.log("after A");
});

getInitialState()가 store를 reset하지 않습니다

getInitialState()는 constructor 값을 읽기만 합니다. reset하려면 값을 setState()에 전달하세요.

store.setState(store.getInitialState());

객체 상태에서 store가 이미 초기 참조를 가리키고 있어도 구독자가 실행되어야 한다면 새 객체를 만들어 전달하세요.

목차