React 上下文 returns promise

React context returns promise

我有一个待办事项应用程序。我正在尝试使用上下文 api(第一次)。我在上下文中添加、删除和获取函数。我可以使用添加和删除但不能 return 获取对状态的响应。它 return 承诺如果我登录; 上下文。我正在使用异步等待。我几乎尝试了我所知道的一切,但无法解决。我的错在哪里? 谢谢。

任务-context.js

import React, { useReducer } from "react";
import TaskContext from "./task-actions";
import { TaskReducer, ADD_TASK, GET_TASKS, REMOVE_TASK } from "./reducers";

const GlobalState = (props) => {
  const [tasks, dispatch] = useReducer(TaskReducer, { tasks: [] });

  const addTask = (task) => {
      dispatch({ type: ADD_TASK, data: task });
  };

  const removeTask = (taskId) => {
      dispatch({ type: REMOVE_TASK, data: taskId });
  };

  const getTasks = () => {
      dispatch({ type: GET_TASKS });
  };

  return (
    <TaskContext.Provider
      value={{
        tasks: tasks,
        getTasks: getTasks,
        addTask: addTask,
        removeTask: removeTask,
      }}
    >
      {props.children}
    </TaskContext.Provider>
  );
};

export default GlobalState;

reducers.js

import taskService from "../Services/tasks-service";

export const ADD_TASK = "ADD_TASK";
export const GET_TASKS = "GET_TASKS";
export const REMOVE_TASK = "REMOVE_TASK";

const addTask = async (data, state) => {
  console.log("Adding : " + data.title);
  try {
    let task = {
      title: data.title,
      description: data.description,
      comment: data.comment,
      progress: data.status
    };
    const res = await taskService.addNewTask(task);
    console.log(res);
    if (res) {
      getTasks();
    }
  } catch (err) {
    console.log(err);
  }
  return;
};

const getTasks = async () => {
  let response = {}
  try {
    const res = await taskService.loadTasks();
    response = res.data
  } catch (err) {
    console.log(err);
  }
  return { tasks: response }
};

const removeTask = async (data) => {
  try {
    await taskService.deleteTask(data.id);
  } catch (err) {
    console.log(err);
  }
};

export const TaskReducer = (state, action) => {
  switch (action.type) {
    case ADD_TASK:
      return addTask(action.data);
    case GET_TASKS:
      console.log(getTasks());
      return getTasks();
    case REMOVE_TASK:
      return removeTask(action.data);
    default:
      return state;
  }
};

任务-actions.js

import React from "react";

export default React.createContext({
  addTask: (data) => {},
  removeTask: (data) => {},
  getTasks: () => {}
});

首先,您得到 return 承诺,因为您 明确 return 承诺:return addTask(action.data)。您的所有操作都是 returning promises into the reducer。

reducer 应该是一个纯函数,这意味着它没有任何副作用(在它自己的范围之外调用代码),或者包含任何异步功能,并且它应该 return 给定相同的数据每次都输入相同的内容。您实际上已经将工作流程回到了前面。

这里有很多需要拆解的地方,所以我将提供伪代码而不是尝试重构整个服务,您将对其有更全面的了解。从减速器开始:

export const TaskReducer = (state, action) => {
  switch (action.type) {
    case ADD_TASK:
      return [...state, action.data];
    case GET_TASKS:
      return action.data;
    case REMOVE_TASK:
      return state.filter(task => task.id !== action.data.id);
    default:
      return state;
  }
};

此减速器描述了状态如何在每个动作完成后更新。它应该知道如何做的就是更新它负责的状态object/array。当涉及到获取数据时,调用 reducer 应该是你必须做的最后一件事。

现在开始行动。添加操作是一个问题,因为它实际上没有 returning 任何数据。最重要的是,它调用 getTasks 时实际上它应该做的只是 return 一项附加任务(应该 从 returned await taskService.addNewTask)。我希望 res.data 实际上是一个任务对象,在这种情况下:

export const addTask = async (data) => {
  try {
    const task = {
      title: data.title,
      description: data.description,
      comment: data.comment,
      progress: data.status
    };
    const res = await taskService.addNewTask(task);
    return res.data;
  } catch (err) {
    return err;
  }
};

getTasks 类似,我假设 await taskService.loadTasks return 是一组任务对象。在这种情况下,我们可以稍微简化一下:

export const getTasks = async () => {
  try {
    const res = await taskService.loadTasks();
    return res.data;
  } catch (err) {
    return err;
  }
};

您的 removeTask 操作基本没问题,尽管您需要 return 错误而不只是记录它们。

请注意,我们现在正在导出这些操作。这样我们现在就可以从 GlobalState 中调用它们了。我们 运行 遇到名称冲突问题,因此我只是强调了导入的操作以用于演示目的。实际上,最好将我们在上一步中所做的所有功能移动到您的 taskService 中,然后直接将其导入 GlobalState 中。由于这是特定于实现的,所以我会把它留给你。

import { 
  TaskReducer, 
  ADD_TASK, 
  GET_TASKS, 
  REMOVE_TASK, 
  addTask as _addTask, 
  getTasks as _getTasks, 
  removeTask as _removeTask,
} from "./reducers";

const GlobalState = (props) => {
  const [tasks, dispatch] = useReducer(TaskReducer, { tasks: [] });

  const addTask = async (task) => {
      const added = await _addTask();

      if (added instanceof Error) {
        // handle error within the application
       return;
      };

      dispatch({ type: ADD_TASK, data: added });
  };

  const removeTask = async (taskId) => {
      const removed = await _removeTask(taskId);

      if (removed instanceof Error) {
        // handle error within the application
        return;
      };

      dispatch({ type: REMOVE_TASK, data: taskId });
  };

  const getTasks = async () => {
      const tracks = await _getTracks();

      if (tracks instanceof Error) {
        // handle error within the application
        return;
      };

      dispatch({ type: GET_TASKS, data: tracks });
  };

  ...
}

希望现在您可以看到工作流程应该如何进行。首先,我们从后端或其他 API 调用数据,然后我们在应用程序内处理响应(例如,调度其他操作以通知新数据的错误或副作用),最后调度新数据进入我们的州。

如开头所述,我提供的基本上是伪代码,所以不要期望它开箱即用。