为什么在将 Typescript 与 React 一起使用时需要执行 export const useAppDispatch = () => useDispatch<AppDispatch>()
Why do I need to do export const useAppDispatch = () => useDispatch<AppDispatch>() when using Typescript with React
我已经使用 JS 对 React 进行了一些工作,但现在我正在创建一个新项目来学习 React with Typescript。我在用JS需要用到dispatch
的时候,直接从react-redux导入了useDispatch:
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 <></>;
};
但是现在在这个 Typescript 项目中,文档说我需要这样做:
// 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();
// ...
}
为什么我需要这样做?
您不需要这样做,但这是一个很好的便利因素,并且可以防止以后出现一些错误。
通常,您必须在每个组件文件中执行此操作:
// 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();
}
花费不多,但重复一遍可能会很烦人。此外,我们看到的最常见的问题之一是人们没有使用 Dispatch
类型的商店特定版本,并且让 TS 告诉他们他们不能发送 thunk,因为它们不是普通的操作对象。
因此,为了保持一致性,我们建议用户始终创建钩子的预类型版本并使用它们,这样他们就不会不小心忘记使用正确的类型:
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();
}
我已经使用 JS 对 React 进行了一些工作,但现在我正在创建一个新项目来学习 React with Typescript。我在用JS需要用到dispatch
的时候,直接从react-redux导入了useDispatch:
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 <></>;
};
但是现在在这个 Typescript 项目中,文档说我需要这样做:
// 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();
// ...
}
为什么我需要这样做?
您不需要这样做,但这是一个很好的便利因素,并且可以防止以后出现一些错误。
通常,您必须在每个组件文件中执行此操作:
// 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();
}
花费不多,但重复一遍可能会很烦人。此外,我们看到的最常见的问题之一是人们没有使用 Dispatch
类型的商店特定版本,并且让 TS 告诉他们他们不能发送 thunk,因为它们不是普通的操作对象。
因此,为了保持一致性,我们建议用户始终创建钩子的预类型版本并使用它们,这样他们就不会不小心忘记使用正确的类型:
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();
}