Answer a question

I am implementing a login functionality with React and Redux-Toolkit. However when trying to dispatch the action created by createAsyncThunk function I get the error:

Argument of type 'AsyncThunkAction<User, UserCredentials, {}>' is not assignable to parameter of type 'AnyAction'. Property 'type' is missing in type 'AsyncThunkAction<User, UserCredentials, {}>' but required in type 'AnyAction'.ts(2345)

I searched over Google for possible solutions however cannot find any that suites my case. Here is my implementation which is done according to the official Redux-Toolkit documentation.

user-slice.ts:

    export interface User {
      UserId: string;
      Name: string;
      Token: string;
    }
    
    export interface UserCredentials {
      username: string;
      password: string;
    }
    
    interface AuthState {
      currentUser: User | null;
      loading: boolean;
      error: string | null;
    }
    
    const initialState: AuthState = {
      currentUser: null,
      loading: false,
      error: null
    };
    
    export const userLogin = createAsyncThunk<User, UserCredentials>(
      'users/login',
      async (credentials: UserCredentials) => {
        const response = await fetch(`${apiRest()}login`, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify(credentials)
        });
        console.log(await response.json());
        return (await response.json()) as User;
      }
    );
    
    export const userSlice = createSlice({
      name: 'users',
      initialState,
      reducers: { },
      extraReducers: (builder) => {
        builder
          .addCase(userLogin.pending, state => {
            state.currentUser = null;
            state.loading = true;
            state.error = null;
          })
          .addCase(userLogin.fulfilled, (state, action) => {
            state.loading = false;
            state.currentUser = action.payload;
            state.error = null;
          })
          .addCase(userLogin.rejected, (state, action) => {
            state.currentUser = null;
            state.loading = false;
            if(action.payload) {
              state.error = action.payload as string;
            } else {
              state.error = 'Failed user to login';
            }
          });
      }
    });
    
    export default userSlice.reducer;

store.ts:

export const store = configureStore({
  reducer: {
    user: userReducer,
  }
});

export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch

hooks.ts:

export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;

login-page.tsx:

export const LoginPage: React.FC = () => {
  const dispatch = useAppDispatch();

  const onLoginSubmit =
  useCallback(
    (login, password) =>   
      // Getting the following error here:   
      // Argument of type 'AsyncThunkAction<User, UserCredentials, {}>' is not assignable to parameter of type 'AnyAction'.
      // Property 'type' is missing in type 'AsyncThunkAction<User, UserCredentials, {}>' but required in type 'AnyAction'.
      dispatch(userLogin({username: login, password})),
    [dispatch]
  );

  const loginErrorText = useSelector(loginError);

  return (
    <div>
      <LoginForm
        onSubmit={onLoginSubmit}
        loginError={loginErrorText}
      />
    </div>
  );
};

Thanks in advance for any help!

Answers

Since your setup seems to be correct I would assume you have a rare error where redux 4.0.5 and redux 4.1.0 are installed side-by-side in your node_modules. I would check for that.

Logo

React社区为您提供最前沿的新闻资讯和知识内容

更多推荐