Преобразовать функцию реагирования стрелка отправки в Tyescript - PullRequest
1 голос
/ 04 июля 2019

В моем ES6 Javascript реагировать / редукционный код у меня есть что-то вроде:

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

Как я могу преобразовать это в машинопись? И не используя Redux, а React useReducer

Моя неудачная попытка была:

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

получил ошибки:

  • Параметр «dispatch» неявно имеет тип «any» .ts (7006)
  • Тип элемента списка '(отправка: любой) => void' нельзя назначить типу 'void'.ts (2322)

1 Ответ

1 голос
/ 05 июля 2019

То, что вы пытаетесь достичь, - это работа в 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>;
}

Я добавил комментарии к коду для ясности.

И рабочий пример здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...