Issue encountered in TypeScript and Redux Toolkit when attempting to use useDispatch.withTypes. The error message "Not a function" is displayed

Looking to improve my understanding of Redux-Toolkit, I've encountered some dispatch errors.

authSlice.ts

import { createAppSlice } from "@/lib/createAppSlice";
import type { PayloadAction } from "@reduxjs/toolkit";

export interface IAuthState {
  authState: boolean;
}

const initialState: IAuthState = {
  authState: false,
};

export const authSlice = createAppSlice({
  name: "auth",
  initialState,
  reducers: {
    setAuthState: (state, action: PayloadAction<boolean>) => {
      state.authState = action.payload;
    },
  },
});

export const { setAuthState } = authSlice.actions;
export const authReducer = authSlice.reducer;

store.ts

import type { Action, ThunkAction } from "@reduxjs/toolkit";
import { combineSlices, configureStore } from "@reduxjs/toolkit";
import { counterSlice } from "./features/counter/counterSlice";
import { quotesApiSlice } from "./features/quotes/quotesApiSlice";
import { authSlice } from "./features/auth/authSlice";

const rootReducer = combineSlices(counterSlice, quotesApiSlice, authSlice);

export type RootState = ReturnType<typeof rootReducer>;

export const makeStore = () => {
  return configureStore({
    reducer: rootReducer,
    middleware: (getDefaultMiddleware) => {
      return getDefaultMiddleware().concat(quotesApiSlice.middleware);
    },
  });
};

export type AppStore = ReturnType<typeof makeStore>;
export type AppDispatch = AppStore["dispatch"];
export type AppThunk<ThunkReturnType = void> = ThunkAction<
  ThunkReturnType,
  RootState,
  unknown,
  Action
>;

hooks.ts

// Centralizing pre-typed Redux hooks for easy re-export.
import { useDispatch, useSelector, useStore } from "react-redux";
import type { AppDispatch, AppStore, RootState } from "./store";

// Enhanced versions of `useDispatch` and `useSelector` used throughout the app
export const useAppDispatch = useDispatch.withTypes<AppDispatch>();
export const useAppSelector = useSelector.withTypes<RootState>();
export const useAppStore = useStore.withTypes<AppStore>();

authUpdater.tsx

This file is where the dispatch function is being utilized.

import React from "react";
import { setAuthState } from "@/lib/features/auth/authSlice";
import { useAppDispatch } from "@/lib/hooks";

export const AuthUpdater = () => {
  const dispatch = useAppDispatch();
  return (
    <div>
      <button onClick={() => dispatch(setAuthState(true))}>Log in</button>
      <button onClick={() => dispatch(setAuthState(false))}>Log out</button>
    </div>
  );
};

Encountering errors with the dispatch function:

react_redux__WEBPACK_IMPORTED_MODULE_0__.useDispatch.withTypes is not a function

Answer №1

Encountered a similar issue when using redux-toolkit with Next.js and TypeScript. I managed to resolve the problem by ensuring that my package.json had the same versions of @reduxjs/toolkit and react-redux libraries as those specified in the package.json of the Vercel Next.js with Redux Toolkit example. Additionally, I included use client at the top of my .tsx file/component.

Answer №2

It seems like the issue you're encountering is related to how you're creating the hooks. I noticed that you referenced a method in the react-redux documentation, but I personally haven't used this approach before. Make sure your react-redux version is up to date, at least v9.1.0 for the .withTypes feature.

export type AppDispatch = typeof store.dispatch;
export type RootState = ReturnType<typeof store.getState>;
export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
export const useAppStore: () => AppStore = useStore;

This is the version I typically rely on. Feel free to reach out if you encounter any challenges or need further clarification.

Update: I suspect the problem lies in the following section:

export type AppDispatch = AppStore["dispatch"];

I recommend making a small tweak to the store declaration as follows:

export const makeStore = configureStore({
    reducer: rootReducer,
    middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(quotesApiSlice.middleware),
  });

By updating the store declaration, makeStore will be of type Store instead of type () => (Store), which should hopefully resolve your issue.

export type AppDispatch = typeof store.dispatch;

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it possible to implement a page transition using preact?

I've been experimenting with creating a page transition using preact-router. I attempted to use the preact-transition-group package along with the preact-css-transition-group package, but encountered an error. Despite this, here is my basic setup: imp ...

react-mock-store: Error - the middleware function is not defined

In my current setup, I am utilizing jest for testing with React and Typescript. import configureStore from "redux-mock-store"; import thunk from "redux-thunk"; const mockStore = configureStore([thunk]); it("should handle fetchCha ...

Does the class effectively implement the interface even if the method of a member variable has undefined arguments?

Let's take a closer look at my code, which lacks proper descriptions. Here is the interface: interface IModel<T = any> { effects: { [key: string]: (getState: () => T) => void; }; } interface IState { name: string; age: numbe ...

Generating dynamic rows and columns with Angular and Bootstrap in real time

I am looking to dynamically generate rows in an angular template, with each row containing 4 columns. For example, if the input is 40, the output should have 10 rows, each consisting of 4 columns. I am using bootstrap for my template layout. Below is what ...

"Facing a challenge with Angular 2 where an HTTP request is being triggered twice

After thorough research on Stack Overflow, I can confidently say that the issue is not with my code. However, my REST APIs are being called twice. Here is a snippet of my code: Component: export class Component { constructor(private _nServ ...

What is the best way to eliminate the final character in an input value once it has passed through regex validation in Angular8

Hello! I am attempting to remove the last digit of a string and update the input value each time my function checks if the input value passes a regex test on keypress. Initially, it works correctly, but then it adds an extra digit. After that, it works a ...

Sending users to either Page A or Page B depending on the response received from the API

Currently facing a dilemma. Imagine having a main hub page where you can navigate to either page A or page B. On this main page, there is a list of items. The goal is to trigger a GET API call upon clicking any item in the list. Based on a boolean field i ...

Guide to integrating an Angular 6/7 project as a dynamic plugin within a separate Angular 6/7 project

Currently embarking on a new project in Angular 7, however facing the challenge of incorporating 6 to 8 existing projects into this new platform dynamically as plugins. Your input on the feasibility and thoughts about this strategy would be greatly appreci ...

Struggling to create a NextJS application on local machine while implementing Firestore

Currently in the process of developing a web application, where I am retrieving data from Firestore using both getStaticProps and getStaticPaths on the client-side as well as the server-side. Everything has been functioning smoothly for several months now ...

Updating text inputs in Angular can be done more efficiently using Angular Update

I need to make adjustments to an Angular application so that it can run smoothly on older machines. Is there a more efficient method for updating a text input field without using (keyup) to update after each keystroke? I haven't been able to find any ...

Does moment/moment-timezone have a feature that allows for the conversion of a timezone name into a more easily comprehendible format?

Consider this example project where a timezone name needs to be converted to a more readable format. For instance: input: America/Los_Angeles output: America Los Angeles While "America/Los_Angeles" may seem human-readable, the requirement is to convert ...

A duplicate H5P Instance has been detected in a ReactJS environment

I've been working on developing a standalone h5p plugin in React (Next.js). I pass the path as a prop to a Modal Component, which then renders the h5p activity. useEffect(() => { const initH5p = async (contentLocation) => { const { H5 ...

Is there a way to delete values from a JavaScript object and include an index column?

I currently have this incoming dataset: [] 0:{"time": 1525355921817, "sym": "AAPL", "price": 169.16, "size": 98, "stop": false, …} 1:{"time": 1525355923216, "sym": "AAPL", "price": 170.15, "size": 6, "stop": false, …} 2:{"time": 1525355923216, "sym": " ...

Is it possible to use line breaks to differentiate properties?

The handbook addresses The handbook states that you can separate properties using , or ;, and the last separator is optional in either case. Is it possible to use line breaks to separate object properties like this? If so, where is this information docu ...

Step-by-step guide on incorporating HTML into a popover within Angular4

After successfully implementing a hover popover in Angular using PopoverModule from ngx-popover, I now need to modify the content inside the popover. My search led me to this example: <ng-template #popContent>Hello, <b& ...

Unable to locate "angular", attempting to retrieve and validate values from the HTML form

I'm relatively new to Angular and I'm looking to utilize angular.module('FooApp', []); in order to fetch HTML form data and conduct validation within my .ts component file. Unfortunately, it appears that "angular" isn't being reco ...

Switching a react virtualized table from JavaScript to TypeScript can uncover some type-related challenges

I have implemented the following demo in my React project: https://codesandbox.io/s/react-virtualized-table-checbox-stackoverflow-rbl0v?fontsize=14&hidenavigation=1&theme=dark&file=/src/App.js However, I am encountering issues with the code sni ...

Troubleshooting Service Angular's Http Subscription Issue

I am currently working on a project that involves retrieving data from a custom server. I have created an httpclient service to handle requests, but I am facing an issue. When I attempt to subscribe and pass data to the component, nothing happens. However, ...

Custom type checker that validates whether all properties of a generic object are not null or undefined

In an attempt to create a user-defined type guard function for a specific use-case, I am faced with a challenge: There are over 100 TypeScript functions, each requiring an options object. These functions utilize only certain properties from the object wh ...

Error message indicating that the host has been configured in both the settings() and useEmulator() functions for the Firebase Firestore emulator, therefore the emulator host will

Initially, I encountered the complete error message. @firebase/firestore: Firestore (8.1.1): Host has been set in both settings() and useEmulator(), emulator host will be used Error [FirebaseError]: Firestore has already been started and its settings c ...