【问题标题】:Typescript integration with complex redux actions and reducersTypescript 与复杂的 redux 操作和 reducer 集成
【发布时间】:2020-07-15 10:14:24
【问题描述】:

我现在是 typescript 的新手,我正在尝试将它与 redux 操作和 reducer 结合起来。我现在遇到一个错误,我想要重构代码的最佳方法。这是我的方法,我需要帮助。

动作

import Axios from "axios";

export const fetchTODO = term => async dispatch => {
  dispatch({ type: "FETCH_TODO" });

  try {
    const response = await Axios.get(`/api/TODO/${term}`, {});
    dispatch({
      type: "FETCH_TODO_SUCCESS",
      payload: response.data
    });
  } catch (error) {
    dispatch({ type: "FETCH_TODO_FAILURE", error });
  }
};

减速器

const initialState = {
  payload: [],
  isLoading: false,
  error: {}
};

export default (state = initialState, { type, payload, error }) => {
  switch (type) {
    case "FETCH_TODO":
      return { ...state, isLoading: true };

    case "FETCH_TODO_SUCCESS":
      return { ...state, payload, isLoading: false };

    case "FETCH_TODO_FAILURE":
      return { ...state, error: error, isLoading: false };

    default:
      return state;
  }
};

打字稿代码

types.tc

export enum ActionTypes {
  fetchTodos,
  fetchTodosSuccess,
  fetchTodosFailure
}

动作

import { ActionTypes } from "./types";
import Axios from "axios";
import { Dispatch } from "redux";

export interface Todo {
  id: number;
  title: string;
  completed: boolean;
}

export interface FetchTodoAction {
  type: ActionTypes;
  payload?: Todo[];
  error?: object;
}

export const fetchTransaction = (term: string) => async (
  dispatch: Dispatch
) => {
  dispatch({ type: ActionTypes.fetchTodos });

  try {
    const response = await Axios.get<Todo[]>(
      `https://jsonplaceholder.typicode.com/todos/`
    );
    dispatch<FetchTodoAction>({
      type: ActionTypes.fetchTodosSuccess,
      payload: response.data
    });
  } catch (error) {
    dispatch({ type: ActionTypes.fetchTodosFailure, error });
  }
};

StateInterface 对象

export interface StateInterface {
  payload?: Todo[];
  isLoading: boolean;
  error?: object;
}

减速器


import { Todo, FetchTodoAction } from "./../actions/index";
import { ActionTypes } from "../actions/types";
import { StateInterface } from ".";

const initialState = {
  payload: [],
  isLoading: false,
  error: {}
};

export const todosReducer = (
  state: StateInterface = initialState,
  { type, payload, error }: FetchTodoAction
) => {
  switch (type) {
    case ActionTypes.fetchTodos:
      return { ...state, isLoading: true };

    case ActionTypes.fetchTodosSuccess:
      return { ...state, payload, isLoading: false };

    case ActionTypes.fetchTodosFailure:
      return { ...state, error: error, isLoading: false };

    default:
      return state;
  }
};

我在代码之后得到了这个错误,任何人都可以告诉我最好的实现

(alias) const todosReducer: (state: StateInterface | undefined, { type, payload, error }: FetchTodoAction) => StateInterface
import todosReducer
No overload matches this call.
  Overload 1 of 3, '(reducers: ReducersMapObject<StateInterface, any>): Reducer<CombinedState<StateInterface>, AnyAction>', gave the following error.
    Argument of type '{ todos: (state: StateInterface | undefined, { type, payload, error }: FetchTodoAction) => StateInterface; }' is not assignable to parameter of type 'ReducersMapObject<StateInterface, any>'.
      Object literal may only specify known properties, and 'todos' does not exist in type 'ReducersMapObject<StateInterface, any>'.

拜托,我真的很期待得到一些支持,并提前感谢您

【问题讨论】:

    标签: reactjs typescript redux action reducers


    【解决方案1】:

    引发此错误是因为 TypeScript 阻止您在需要以下参数(即不是 undefined)时将参数作为选项(即 undefined)。

    您可以通过从 initialState 推断类型来解决此问题。

    例如。 const initialState: StateInterface { ... }

    现在您不再需要在 reducer 参数中设置 state 的类型,因为 TypeScript 知道该值将始终被定义。

    例如。 export const todosReducer = (state = initialState, ...) =&gt; { ... }

    因此,将您的 reducer 代码更改为以下内容:

    import { Todo, FetchTodoAction } from "./../actions/index";
    import { ActionTypes } from "../actions/types";
    import { StateInterface } from ".";
    
    // Define initial state type here
    const initialState: StateInterface = {
      payload: [],
      isLoading: false,
      error: {}
    };
    
    export const todosReducer = (
      state = initialState, // state type is now inferred from initialState
      { type, payload, error }: FetchTodoAction
    ) => {
      switch (type) {
        case ActionTypes.fetchTodos:
          return { ...state, isLoading: true };
    
        case ActionTypes.fetchTodosSuccess:
          return { ...state, payload, isLoading: false };
    
        case ActionTypes.fetchTodosFailure:
          return { ...state, error, isLoading: false };
    
        default:
          return state;
      }
    };
    

    编辑: 如果这仍然不起作用,那么将 { type, payload, error }: FetchTodoAction 更改为 { type, payload, error }: FetchTodoAction | undefined 应该可以解决问题。

    【讨论】:

      猜你喜欢
      • 2016-05-30
      • 1970-01-01
      • 2019-09-03
      • 1970-01-01
      • 1970-01-01
      • 2017-10-03
      • 2017-04-13
      • 2017-03-04
      • 2016-07-10
      相关资源
      最近更新 更多