javascript - 将 React 调度箭头函数转换为 typescript

标签 javascript reactjs typescript ecmascript-6

在我的 ES6 javascript react/redux 代码中,我有类似的东西:

export const myFunction = params => dispatch => {
   ...code
   dispatch(...)
}

如何将其转换为 typescript ?不使用 Redux,而是使用 React useReducer

我失败的尝试是:

export const myFunction = (payload: any): void => dispatch:any => {
  ...code
  dispatch(...)
}

得到错误:

  • 参数“dispatch”隐式具有“any”类型.ts(7006)
  • 列表项类型“(dispatch: any) => void”不可分配给类型“void”.ts(2322)

最佳答案

您试图实现的是在 Redux 中工作并促进 bu Redux-thunk middleware . useReducer Hook 中不存在中间件。所以开箱即用,这是不可能的。

但是你可以这样写自己的中间件

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

关于javascript - 将 React 调度箭头函数转换为 typescript ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56893971/

相关文章:

javascript - google plus 交互式帖子回调

javascript - Reactjs : import and load external js library minified files put inside src

javascript - 如何在正则表达式中检测带标点符号的汉字?

javascript - NextJs - 我们可以在哪里添加 &lt;script&gt; 代码?

javascript - 当使用 fetch、axios 等时,.`catch` 不会处理错误,而是您的应用程序崩溃

javascript - typescript :来自父类(super class)构造函数的成员变量

typescript - 如何更新 React/TypeScript 项目中的快照?

angular - 搜索字段失去焦点

javascript - 解压缩/解压缩 JavaScript 的工具

javascript - javascript 和 jQuery 中的动态 youtube iframe