Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I need to do export const useAppDispatch = () => useDispatch<AppDispatch>() when using Typescript with React

I've worked a bit with React using JS, but now I'm creating a new project to learn React with Typescript. When I was using JS and needed to use dispatch, I just imported useDispatch from react-redux:

import { useDispatch, useSelector } from 'react-redux';
const AuthAppBar = () => {
  const dispatch = useDispatch();
  const isUserLogged = useSelector(authSelector.isUserLogged);
  const { event } = useGoogleAnalytics();

  const userLogout = () => {
    const userManager = authManager.getUserManager();
    dispatch(authActions.setLoggingOut(true));
    userManager.signoutRedirect({ state: { callbackUrl: routes.home.path } });

    event('Account', 'Logout');
  };

  return <></>;
};

But now in this Typescript project the docs says that I need to do like this:

// hooks.ts
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
import type { RootState, AppDispatch } from './store';

// Use throughout your app instead of plain `useDispatch` and `useSelector`
export const useAppDispatch = () => useDispatch<AppDispatch>();


// useGetDeviceById.ts
import { useEffect } from 'react';
import { useHistory, useParams } from 'react-router-dom';
import { useAppDispatch, useAppSelector } from 'src/hooks';

const useGetDeviceById = () => {
  const dispatch = useAppDispatch();
  // ...
}

Why do I need to do it this way?

like image 534
Juliano Nunes Silva Oliveira Avatar asked Dec 30 '25 14:12

Juliano Nunes Silva Oliveira


1 Answers

You aren't required to do this, but it's a nice convenience factor, and can prevent some errors later.

Normally, you'd have to do this in every component file:

// import the RootState type
import { RootState, AppDispatch } from "app/store";
import { useSelector, useDispatch } from "react-redux";

function MyComponent() {
  // Specifically mark the `state` arg as being of type RootState
  const todos = useSelector( (state: RootState) => state.todos);

  // Specifically mark `dispatch` as being a type that understands thunks
  const dispatch : AppDispatch = useDispatch();
}

Not a huge cost, but it can be annoying to repeat that. In addition, one of the most common problems we see is people not using the store-specific version of the Dispatch type, and having TS tell them they can't dispatch thunks because those aren't plain action objects.

So, for consistency, we recommend that users always create pre-typed versions of the hooks and use them, so they don't accidentally forget to use the right types:

import { useAppSelector, useAppDispatch } from "app/hooks";

function MyComponent() {
  // Already knows the state is `RootState`
  const todos = useAppSelector(state => state.todos);

  // Already knows that `dispatch` can accept a thunk
  const dispatch = useAppDispatch();
}
like image 154
markerikson Avatar answered Jan 01 '26 08:01

markerikson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!