Home > Software engineering >  Redux Toolkit middleware with react-redux connector fails
Redux Toolkit middleware with react-redux connector fails

Time:07-17

I migrated redux to @reduxjs/toolkit but I'm having an issue. Everything worked fine without the toolkit middlewares applied. When I started applying some, I got errors.

I have a component:

import React from 'react';
import type { PayloadAction } from '@reduxjs/toolkit';

import { type AppDispatch, appConnect } from '@/store/app';
import { authActions } from '@/store/reducers/auth';

import HeaderView from './Header.view';

interface IPropsFromDispatch {
    logout: () => PayloadAction;
}

interface IProps extends IPropsFromDispatch {}

const Header: React.FC<IProps> = (props: React.PropsWithChildren<IProps>) => {
    const onExitButton = () => {
        props.logout();
    };

    return <HeaderView onExitButton={onExitButton} />;
};

Header.displayName = 'Header';
Header.defaultProps = {};

const mapDispatchToProps = (dispatch: AppDispatch): IPropsFromDispatch => {
    return {
        logout: (): PayloadAction => dispatch(authActions.logout()),
    };
};

export default appConnect(null, mapDispatchToProps)(React.memo(Header));

And I have the following store:

import { configureStore } from '@reduxjs/toolkit';
import { type Connect, connect } from 'react-redux';

import authReducer from './reducers/auth';
import authListenMiddleware from './middlewares/auth';

const store = configureStore({
    reducer: {
        auth: authReducer,
    },
    middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(authListenMiddleware.middleware),
    devTools: process.env.REACT_APP_NODE_ENV === 'development',
});

export type AppState = ReturnType<typeof store.getState>;

export type AppDispatch = typeof store.dispatch;

export const appConnect = connect as Connect<AppState>;

export default store;

When I started to apply middlewares in the store, I got an error in the component file:

TS2769: No overload matches this call.
  The last overload gave the following error.
    Argument of type '(dispatch: AppDispatch) => IPropsFromDispatch' is not assignable to parameter of type 'MapDispatchToPropsParam<IPropsFromDispatch, {}>'.
      Type '(dispatch: AppDispatch) => IPropsFromDispatch' is not assignable to type 'MapDispatchToPropsFactory<IPropsFromDispatch, {}>'.
        Types of parameters 'dispatch' and 'dispatch' are incompatible.
          Type 'Dispatch<Action<unknown>>' is not assignable to type 'ThunkDispatch<{ auth: IAuthState; }, undefined, AnyAction> & ((action: Action<"listenerMiddleware/add">) => UnsubscribeListener) & Dispatch<...>'.
            Type 'Dispatch<Action<unknown>>' is not assignable to type '(action: Action<"listenerMiddleware/add">) => UnsubscribeListener'.
              Type 'Action<"listenerMiddleware/add">' is not assignable to type 'UnsubscribeListener'.
                Type 'Action<"listenerMiddleware/add">' provides no match for the signature '(unsubscribeOptions?: UnsubscribeListenerOptions | undefined): void'.

I've also tried to follow this thread: https://github.com/reduxjs/redux-toolkit/issues/2285

But it didn't help

CodePudding user response:

Copying the answer I provided in the issue thread:

The best fix is don't use connect any more - use the hooks API instead :)

The second-best option is to use the object form of mapDispatch, not the function form.

The third option is to pass mapDispatch as a function directly inline to connect.

  • Related