首页 > 解决方案 > CRA 样板无法读取 Redux -Saga & Reselect & redux-toolkit 中未定义的属性“initialLoad”

问题描述

当我使用 useSelector 挂钩获取数据时出现此错误。我得到导致错误的初始状态未定义。

选择器.ts

import { createSelector } from '@reduxjs/toolkit';
import { RootState } from 'types';
import { initialState } from '.';

const selectSlice = (state: RootState) => state.initialLoad || initialState;
export const selectInitialLoad = createSelector([selectSlice], state => state);

索引.ts

import { PayloadAction } from '@reduxjs/toolkit';
import { createSlice } from 'utils/@reduxjs/toolkit';
import { useInjectReducer, useInjectSaga } from 'utils/redux-injectors';
import { initialLoadSaga } from './saga';
import { InitialLoadState, RepoErrorType } from './types';

export const initialState: InitialLoadState = {
  name: 'initial-load',
  layouts: [],
  loading: false,
  error: null,
};

const slice = createSlice({
  name: 'initialLoad',
  initialState,
  reducers: {
    loadLayout(state) {
      state.loading = true;
      state.error = null;
      state.layouts = [];
    },
    layoutLoaded(state, action: PayloadAction<[]>) {
      const repos = action.payload;
      state.layouts = repos;
      state.loading = false;
    },
    layoutError(state, action: PayloadAction<string | RepoErrorType>) {
      state.error = 'error';
      state.loading = false;
    },
  },
});

export const { actions: appLayoutActions } = slice;

export const useAppLayoutSlice = () => {
  useInjectReducer({ key: slice.name, reducer: slice.reducer });
  useInjectSaga({ key: slice.name, saga: initialLoadSaga });
  return { actions: slice.actions };
};

类型.ts

/* --- STATE --- */
export interface InitialLoadState {
  name: string;
  loading: boolean;
  error?: RepoErrorType | string | null;
  layouts: [];
}
export enum RepoErrorType {
  RESPONSE_ERROR = 1,
  USER_NOT_FOUND = 2,
  USERNAME_EMPTY = 3,
  USER_HAS_NO_REPO = 4,
  GITHUB_RATE_LIMIT = 5,
}

/* 
  If you want to use 'ContainerState' keyword everywhere in your feature folder, 
  instead of the 'InitialLoadState' keyword.
*/
export type ContainerState = InitialLoadState;

减速器.ts

/**
 * Combine all reducers in this file and export the combined reducers.
 */

import { combineReducers } from '@reduxjs/toolkit';

import { InjectedReducersType } from 'utils/types/injector-typings';

/**
 * Merges the main reducer with the router state and dynamically injected reducers
 */
export function createReducer(injectedReducers: InjectedReducersType = {}) {
  // Initially we don't have any injectedReducers, so returning identity function to avoid the error
  if (Object.keys(injectedReducers).length === 0) {
    return state => state;
  } else {
    return combineReducers({
      ...injectedReducers,
    });
  }
}

这是我的configuerStore.ts

    /**
 * Create the store with dynamic reducers
 */

import {
  configureStore,
  getDefaultMiddleware,
  StoreEnhancer,
} from '@reduxjs/toolkit';
import { createInjectorsEnhancer } from 'redux-injectors';
import createSagaMiddleware from 'redux-saga';

import { createReducer } from './reducers';

export function configureAppStore() {
  const reduxSagaMonitorOptions = {};
  const sagaMiddleware = createSagaMiddleware(reduxSagaMonitorOptions);
  const { run: runSaga } = sagaMiddleware;

  // Create the store with saga middleware
  const middlewares = [sagaMiddleware];

  const enhancers = [
    createInjectorsEnhancer({
      createReducer,
      runSaga,
    }),
  ] as StoreEnhancer[];

  const store = configureStore({
    reducer: createReducer(),
    middleware: [...getDefaultMiddleware(), ...middlewares],
    devTools: process.env.NODE_ENV !== 'production',
    enhancers,
  });

  return store;
}

解决向状态添加条件

import { createSelector } from '@reduxjs/toolkit';
import { RootState } from 'types';
import { initialState } from '.';

const selectSlice = (state: RootState) => state && state.initialLoad || initialState;
export const selectInitialLoad = createSelector([selectSlice], state => state);

大多数文件都是创建反应应用程序样板而不更改。我在没有干净设置的 cra 样板模板上尝试了同样的方法,它工作正常,但是在干净和设置之后它不起作用我也需要它

标签: react-reduxredux-sagaredux-toolkitreselectreact-boilerplate

解决方案


推荐阅读