我对使用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
成语?
商店:
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
)
您可以创建一个类型化的自定义钩子:
type Dispatch = <TReturnType>(action: Actions) => TReturnType;
const useTypedDispatch = () => useDispatch<Dispatch>();
其中Actions
是您所有可用操作的联合,例如问题中的CounterAction
。您可以将其用作:
const dispatch = useTypedDispatch()