我对使用useDispatch
的好处和最佳实践感到困惑。
当前,我通过导出bindActionCreators
的结果来抽象访问我的商店(见下文),该结果允许使用类似组件这样的语句进行受控访问
import {counterActions} from "./store"
//...
counterActions.reset()
具有对参数和结果的完整类型检查,以及对单个操作的代码完成。
但是如果我改用useDispatch
和
import { useDispatch } from "react-redux"
const dispatch = useDispatch()
// ...
dispatch({type: "RESET"})
我在调用dispatch
时没有进行类型或参数检查,并且可以轻松输入废话,例如
dispatch({junk: "GARBAGE", morejunk: "MOREGARBAGE"})
除非我在组件中使用类似的注释
import { CounterAction } from "../store"
// ...
const dispatch: (action: CounterAction) => void = useDispatch()
或在我的商店中创建类似
的包装export function useMyDispatch(): (action: CounterAction) => void {
return useDispatch()
}
然后在我的组件中使用它。
为什么useDispatch
比我的counterActions
好?是否有误用或遗漏的useDispatch
用法成语?
store.ts :
import { createStore } from "redux"
import { bindActionCreators } from 'redux'
interface CounterState {
count: number;
}
type CounterAction =
| { type: 'INCREMENT'; step: number }
| { type: 'RESET' }
const initialState: CounterState = {count: 0}
const counterReducer = (state = initialState, action: CounterAction): CounterState => {
switch (action.type) {
case 'INCREMENT':
return {...state, count: state.count + action.step}
case "RESET":
return {...state, count: 1}
default:
return state
}
}
// Use only for Provider
export const store = createStore(counterReducer)
const increment = (step: number = 1): CounterAction => ({ type: "INCREMENT", step: step })
const reset = (): CounterAction => ({ type: "RESET" })
export const counterActions = bindActionCreators(
{ increment, reset },
store.dispatch
)
答案 0 :(得分:2)
您可以创建类型化的自定义挂钩:
type Dispatch = <TReturnType>(action: Actions) => TReturnType;
const useTypedDispatch = () => useDispatch<Dispatch>();
其中Actions
是您所有可用操作的并集,例如问题中的CounterAction
。您可以将其用作:
const dispatch = useTypedDispatch()