在我的ES6 javascript react / redux代码中,我有类似的内容:
export const myFunction = params => dispatch => {
...code
dispatch(...)
}
如何将其转换为打字稿?而不是使用Redux而是React useReducer
我失败的尝试是:
export const myFunction = (payload: any): void => dispatch:any => {
...code
dispatch(...)
}
忘记了错误:
答案 0 :(得分:1)
您要实现的目标是在Redux中使用,并促进bu Redux-thunk middleware。 useReducer
挂钩中没有中间件。因此,这是不可能的。
但是您可以这样编写自己的中间件
import * as React from 'react';
interface FuncState {
prop1: string;
prop2: string;
}
interface FunctAction1 {
type: 'SET_PROP1'; // Action type property has type of 'SET_PROP1'. This is not string, it is type 'SET_PROP1'. The only value type may have is 'SET_PROP1'.
prop1: string;
}
interface FunctAction2 {
type: 'SET_PROP2';
prop2: string;
}
// Here we create union of actions to properly type Reducer
type KnownActions = FunctAction1 | FunctAction2;
const FuncInitState: FuncState = {
prop1: '',
prop2: ''
}
function isFunction(f: any): f is Function {
return typeof f === "function";
}
function useThunkReducer<S, A>(reducer: React.Reducer<S, A>, initialState: React.ReducerState<React.Reducer<S, A>>):
[S, (action: A | ((dispatch: React.Dispatch<A>, state: S) => void)) => void]
{
const [state, dispatch] = React.useReducer(reducer, initialState);
// Essentially this is middleware
const thunkDispatch = (action: A
| ((dispatch: React.Dispatch<A>, state: S) => void)): void => {
if (isFunction(action)) { // This is type guard
return action(dispatch, state);
}
return dispatch(action);
};
return [state, thunkDispatch];
}
const FuncReducer: React.Reducer<FuncState, KnownActions> = (state, action) => {
switch (action.type) {
case 'SET_PROP1':
// action will have type of FunctAction1 as action.type has value 'SET_PROP1'
return { ...state, prop1: action.prop1 }
case 'SET_PROP2':
return { ...state, prop2: action.prop2 }
default:
throw new Error('FuncReducer do not have default');
}
}
const myClickAction = (prop1: string) => (dispatch: React.Dispatch<KnownActions>) => {
console.log(prop1);
dispatch({ type: 'SET_PROP1', prop1: "some value" });
}
const FuncCmp: React.FunctionComponent = () => {
const [state, dispatch] = useThunkReducer(FuncReducer, FuncInitState);
return <div>
FuncCmp
<button onClick={(e) => dispatch(myClickAction("some value"))}>Set prop1</button>
<button onClick={(e) => dispatch({ type: 'SET_PROP2', prop2: "another value" })}>Set prop2</button>
<div>Prop1: {state.prop1}</div>
<div>Prop2: {state.prop2}</div>
</div>;
}
为了清楚起见,我在代码中添加了注释。
工作示例为here