Получение ошибки TypeScript с отправкой redux в моем приложении React - PullRequest
1 голос
/ 17 июня 2020

Новичок в React, я пытаюсь реализовать поток с помощью Redux, но у меня возникает ошибка TypeScript при вызове диспетчеризации с моим асинхронным действием.

Вот мой App.tsx:

import React from 'react';
import { IonApp } from '@ionic/react';
import Main from './pages/Main';
import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import rootReducer from './flux/reducers';
import { loginAttempt } from './flux/actions';
import thunkMiddleware from 'redux-thunk';
import { createLogger } from 'redux-logger';

const loggerMiddleware = createLogger();

const store = createStore(rootReducer, 
  applyMiddleware(
    thunkMiddleware, loggerMiddleware
  )
);

let promise = store.dispatch(loginAttempt('test@host.org','test'));

promise.then(() => console.log(store.getState()));

class App extends React.Component {

  render() {

    return (
      <Provider store={store}>
        <IonApp>
          <Main/>
        </IonApp>
      </Provider>
  )}
}

export default App;

Мои действия:

import fetch from 'cross-fetch';
import { Dispatch, Action } from 'redux';

export const LOGIN_REQUEST = 'LOGIN_REQUEST';
export const LOGIN_FAILURE = 'LOGIN_FAILURE';
export const LOGIN_SUCCESS = 'LOGIN_SUCCESS';

export function loginRequest() {
  return { type: LOGIN_REQUEST }
}

export function loginFailure(error: string) {
  return { type: LOGIN_FAILURE, error }
}

export function loginSuccess(sessionId: string) {
  return { type: LOGIN_SUCCESS, sessionId }
}

export async function loginAttempt(email: string, password: string) {

  return async function (dispatch: Dispatch<Action<any>>) {

    dispatch(loginRequest());

    return fetch("http://127.0.0.1:5000/login", {
      method: "post",
      headers: new Headers({
          "Content-Type": "application/json",
          Accept: "application/json",
      }),
      body: JSON.stringify({email, password})
      })
      .then(
        response => response.json()
      )
      .then(json =>
        dispatch(loginSuccess(json))
      )
  }
}

И редукторы:

import { LOGIN_REQUEST, LOGIN_FAILURE, LOGIN_SUCCESS } from './actions';
import { combineReducers } from 'redux';

const initialState = {connected: false, sessionId: "", isFetching: false, failed: false, error:""};

function login(state = initialState, action: any) {
    switch (action.type) {
        case LOGIN_REQUEST:
            return Object.assign({}, state, {
                isFetching: true
            });

        case LOGIN_FAILURE:
            return Object.assign({}, state, {
                isFetching: false,
                failed: true,
                error: action.error
            });

        case LOGIN_SUCCESS:
            return Object.assign({}, state, {
                connected: true,
                isFetching: false,
                sessionId: action.sessionId
            });

        default:
            return state
    }
}

const rootReducer = combineReducers({
    login
})

export default rootReducer;

Это вызывает ошибку TypeScript при компиляции:

Argument of type 'Promise<(dispatch: Dispatch<Action<any>>) => Promise<{ type: string; sessionId: string; }>>' is not assignable to parameter of type 'AnyAction'.
  Property 'type' is missing in type 'Promise<(dispatch: Dispatch<Action<any>>) => Promise<{ type: string; sessionId: string; }>>' but required in type 'AnyAction'.  TS2345

Я уверен, что это какая-то глупость с моей стороны, но я не могу найти, какой тип мне нужно изменить, чтобы это работало.

Есть идеи, что я делаю не так?

1 Ответ

0 голосов
/ 24 июня 2020

Друг в конце концов помог мне исправить это, мне нужно было преобразовать промежуточное ПО как ThunkMiddleware:

const store = createStore(
  rootReducer, 
  applyMiddleware(
    thunkMiddleware as ThunkMiddleware<typeof initialState, Action<any>>
  )
);

initialState импортируется из моего редуктора.

Также моя функция loginAttempt была изменена на не возвращать обещание напрямую:

export function loginAttempt(email: string, password: string) {
  return async function (dispatch: any) {
    [...]
  }
}
...