非 hacky 回答入站!
最短的答案:
链接到 Redux Toolkit 文档以创建类型化的 react-redux 钩子:https ://react-redux.js.org/using-react-redux/usage-with-typescript#define-root-state-and-dispatch-types
(虽然这是 Redux Toolkit 文档的链接,但我相信这种技术仍然适用于“vanilla” react-redux
。如果我错了,请有人用评论纠正我。)
简答:
在useSelector
本身挂钩是不知道应该应用到你想使用的状态打字的。您必须做几行工作才能获得类型安全!使用链接中显示的技术,每次使用它时,您都将获得适合您的状态的类型。您将创建一个单行自定义钩子,该钩子利用useSelector
带有从根状态推断出的类型的本机钩子来找出您的状态类型应该是什么。
更长的答案:
在useSelector
本身挂钩是不知道应该应用到你想使用的状态打字的。为了使您的商店类型被捕获并应用于您的useSelector
挂钩,您需要跳过两个小箍。我们也将照顾您的useDispatch
钩子。
步骤1
让我们从 store 中获取推断的类型。为此,我们将前往创建我们的 store 的位置,并使用一些 Typescript 魔法从状态中获取推断类型:
// Copied from Redux Toolkit docs that are linked above
// store.ts
import rootReducer from './rootReducer'
const store = createStore(rootReducer)
export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch
短暂的停顿以解压第 6 行和第 7 行:
第 6 行: export type RootState = ReturnType<typeof store.getState>
现在将这些部分放在一起!:无论从 store.getState 返回什么,我都希望将类型存储为RootState
变量!
第 7 行: export type AppDispatch = typeof store.dispatch
typeof
意思是“告诉我这东西的类型是什么。”
store.dispatch
意思是“我想要用于将操作分派到商店的分派对象。”
现在将这些部分放在一起!:从商店中获取 dispatch 对象,将其分解为类型,并将其存储在AppDispatch
变量中!
第2步
现在我们已经从 store 和 dispatch 推断出类型,我们可以将它们应用于我们的钩子。我们将通过创建一个自定义钩子来做到这一点,这样我们就不必每次去使用它们时都输入我们的钩子:
// Copied from Redux Toolkit docs that are linked above
// 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>()
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
在这里,我们将我们创建的类型store.ts
应用到我们通常在 中使用的useDispatch
和useSelector
钩子react-redux
。从现在开始,当您使用新的自定义钩子时,您将为您设置类型!
瞧!您现在在 react-redux 钩子实现中具有类型安全性!