Middleware
미들웨어는 store가 다음 값을 적용하기 전에 setState()를 감쌀 수 있게 해줍니다.
Public method는 다음과 같습니다.
pushMiddleware(middleware: Middleware<T>): void
unshiftMiddleware(middleware: Middleware<T>): void내부 미들웨어 형태는 다음과 같습니다.
type SetStateAction<T> = T | ((prevState: T) => T);
type Middleware<T> = (
nextState: SetStateAction<T>,
next: (value: SetStateAction<T>) => void
) => void;순서
pushMiddleware()는 미들웨어 배열 끝에 추가합니다. unshiftMiddleware()는 배열 앞에 추가합니다. setState() 동안 store는 reduceRight를 사용하므로 배열의 첫 미들웨어가 업데이트를 먼저 받습니다.
const calls: string[] = [];
store.pushMiddleware((state, next) => {
calls.push("A before");
next(state);
calls.push("A after");
});
store.pushMiddleware((state, next) => {
calls.push("B before");
next(state);
calls.push("B after");
});
store.setState((prev) => prev);
// A before, B before, B after, A afterunshiftMiddleware()를 사용하면 새 미들웨어가 이후 업데이트를 가장 먼저 받습니다.
업데이트 변환하기
미들웨어는 다른 값이나 updater를 next()에 전달할 수 있습니다.
store.pushMiddleware((nextState, next) => {
next((prev) => {
const resolved = typeof nextState === "function" ? nextState(prev) : nextState;
return { ...resolved, updatedAt: Date.now() };
});
});업데이트 차단하기
미들웨어는 next()를 호출하지 않는 방식으로 업데이트를 차단할 수 있습니다. 이 경우 구독자가 실행되지 않고 호출자도 차단 이유를 return value로 받지 못하므로 조심해서 사용하고 이유를 문서화하세요.
store.pushMiddleware((nextState, next) => {
if (isInvalid(nextState)) return;
next(nextState);
});Side effect
미들웨어는 setState() 안에서 동기적으로 실행됩니다. setState()가 기다리거나 throw하길 의도한 경우가 아니라면 긴 작업, 네트워크 호출, timer는 미들웨어 chain 밖에 두세요.