javascript TypeError:store.dispatch不是函数

ui7jx7zq  于 2023-02-02  发布在  Java
关注(0)|答案(1)|浏览(191)

我正在沿着Redux Writing Test guide来测试我的Redux/TypeScript应用程序。我遇到了TypeError: store.dispatch is not a function错误。
我按照这个suggestion导出和使用一个已经配置好的存储对象,但是我仍然收到这个错误。
(my尝试)

export default function setupStore(preloadedState?: PreloadedState<RootState>) {
    return configureStore({
        reducer: persistedReducer,
        middleware: (getDefaultMiddleware) =>
            getDefaultMiddleware({
                serializableCheck: {
                    ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
                },
            }),
        preloadedState,
    });
};

下面是包含相关代码的文件。
test-utils.tsx

import setupStore from '../store';

interface ExtendedRenderOptions extends Omit<RenderOptions, 'queries'> {
    preloadedState?: PreloadedState<RootState>;
    store?: AppStore;
}

export function renderWithProviders(
    ui: React.ReactElement,
    {
        preloadedState = {},
        store = setupStore(preloadedState),
        ...renderOptions
    }: ExtendedRenderOptions = {},
) {
    function Wrapper({ children }: PropsWithChildren<{}>): JSX.Element {
        return <Provider store={store}>{children}</Provider>;
    }

    return { store, ...render(ui, { wrapper: Wrapper, ...renderOptions }) };
}

store.ts

const persistConfig = {
    key: 'root',
    version: 1,
    storage,
};

const rootReducer = combineReducers({ user: userReducer, cart: cartReducer });
const persistedReducer = persistReducer(persistConfig, rootReducer);
export default function setupStore(preloadedState?: PreloadedState<RootState>) {
    return configureStore({
        reducer: persistedReducer,
        middleware: (getDefaultMiddleware) =>
            getDefaultMiddleware({
                serializableCheck: {
                    ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
                },
            }),
        preloadedState,
    });
};

export let persistor = persistStore(setupStore as any);
export type RootState = ReturnType<typeof rootReducer>;
export type AppStore = ReturnType<typeof setupStore>;
export type AppDispatch = AppStore['dispatch'];

Navbar.tsx

const Navbar: React.FC = () => {
    const cartQuantity = useAppSelector((state: RootState) => state.cart.cartQuantity);
    const { currentUser } = useAppSelector((state: RootState) => state.user);

    return (
        <Language>EN</Language>
    );
};

Navbar.test.tsx

it('renders same span text in Navbar component', async () => {
    renderWithProviders(<Navbar />);
    const spanElement = screen.getByText(/EN/i);
    expect(spanElement).toBeInTheDocument();
});
b4lqfgs4

b4lqfgs41#

我想你基本上遇到了和你用setupStore函数链接到的帖子一样的问题,需要调用它来获得一个实际的store对象。
AppDispatch必须是typeof store.dispatch。请尝试执行以下操作,其中AppDispatch是从AppStore类型中“选取”的。

export default function setupStore(preloadedState?: PreloadedState<RootState>) {
  return configureStore({
    reducer: persistedReducer,
    middleware: (getDefaultMiddleware) =>
      getDefaultMiddleware({
        serializableCheck: {
          ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
        },
      }),
    preloadedState,
  });
};

...

export type AppStore = ReturnType<typeof setupStore>;
export type AppDispatch = Pick<AppStore, "dispatch">;

相关问题