lidongyangLeo / LearnNotes

记录学习的点点滴滴
MIT License
0 stars 0 forks source link

RTK loading #48

Open lidongyangLeo opened 1 year ago

lidongyangLeo commented 1 year ago

interface LoadingSlice {
  loading: boolean;
  pendingActions: string[];
}

const initialState = {
  loading: false,
  pendingActions: [],
} as LoadingSlice;

// 既存踏襲。ヘッダーバーに出すコンポーネント用のslice actionsはbackdropを出さない
const noLoadingSliceName = [
  topLayoutSliceName,
  bookmarkSliceName,
  recentHistorySliceName,
  sdbNotificationSliceName,
].map((name) => name + "/");
const isNoLoadingActions = (action: AnyAction) =>
  noLoadingSliceName.some((name) => action.type.startsWith(name));

type GenericAsyncThunk = AsyncThunk<unknown, unknown, any>;
type PendingAction = ReturnType<GenericAsyncThunk["pending"]>;
type FinishedAction =
  | ReturnType<GenericAsyncThunk["rejected"]>
  | ReturnType<GenericAsyncThunk["fulfilled"]>;

const isPendingAction = (action: AnyAction): action is PendingAction =>
  !isNoLoadingActions(action) && action.type.endsWith("pending");
const isFinishedAction = (action: AnyAction): action is FinishedAction =>
  !isNoLoadingActions(action) &&
  (action.type.endsWith("fulfilled") || action.type.endsWith("rejected"));

const loadingSlice = createSlice({
  name: "loading",
  initialState,
  reducers: {},

  extraReducers: (builder) => {
    builder
      .addMatcher(isPendingAction, (state, action) => {
        state.pendingActions.push(action.meta.requestId);
        state.loading = true;
      })
      .addMatcher(isFinishedAction, (state, action) => {
        state.pendingActions = state.pendingActions.filter(
          (id) => id !== action.meta.requestId
        );
        state.loading = state.pendingActions.length !== 0;
      });
  },
});

// export const {} = loadingSlice.actions;
export default loadingSlice.reducer;