Reputation: 8177
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?
Upvotes: 16
Views: 19895
Reputation: 67539
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();
}
Upvotes: 27