您的示例不完整,并且按照您如何得出那个过于简单的解决方案令人沮丧。在研究它之后我意识到,你可能有一些 ReadableAPI.js 文件,你应该在某个地方发布可能是使用 fetch 的配置,在其中你可能有这样的东西:
export const getCategories = () =>
fetch('http://localhost:3001/categories', {headers})
.then(res => res.json())
.then(data => console.log(data))
这与你的:
ReadableAPI.getCategories().then((categories)=>{
console.log('after getCategories', categories)
this.props.dispatch(addCategories(categories))
})
因此,在此解决方案中,您将返回一个 Promise,该对象本质上是在完成诸如网络请求之类的一些工作时向我们提供通知,并且为了获得通知,我们链接在我们传递的 .then() 函数上像您一样的箭头函数:then((categories)=>,并且该箭头函数将在将来的某个时候被调用。
您似乎将该数据称为categories,并且您正在控制台记录'after Categories', categories。
我们需要知道的是附加到categories 对象的不同属性是什么?它有data 属性吗?它是否有一个 results 属性,其中包含一些实际数据?是否有包含任何数据的categories.data.results?
所以让我们说所有问题的答案都是肯定的。
为了处理异步请求,您正在以一种有点困难的方式进行处理,因为它不仅仅是代码的 sn-p,还有 ReadableAPI.js 文件中的内容,对吧?另外,您使用的 Promises 可能会有点麻烦,并且您已经将两个文件放在一起只是为了处理异步请求,如果它只是一个普通的 Reactjs 应用程序,这将是可以的,但是您提到了您的方法作为 Redux 的替代方案-Thunk 这意味着使用 Redux。
对于您在香草 Reactjs 空间中的方法,我将使用 Axios 并实现 async/await 语法,但涉及 Redux,您不想使用 Promise。
现在,我必须在 ReadableAPI.js 文件中编写的动作创建器在 Redux 环境中不起作用,因为它不返回纯 JavaScript 动作对象,因此我们必须使用自定义中间件,如错误所示去做。
那么像 Redux-Thunk 这样的中间件是如何工作的呢?
Redux Thunk 从本质上放宽了动作创建者的规则。
Redux-Thunk 的目的不是传递一个请求对象,它会带走它并为你工作。
Redux-Thunk 是一个通用中间件,它允许我们处理异步动作创建者,但它也允许我们做许多其他事情。
使用 Redux Thunk,您的操作创建者可以返回一个操作对象。如果你返回一个动作对象,它仍然必须有一个类型属性,如果它是一个被返回的动作对象,它也可以有一个有效负载。
Redux-Thunk 做的另一件事是允许你返回一个动作对象或一个函数。
如果你返回一个函数,Redux-Thunk 会自动为你调用那个函数。
就是这样,这就是 Redux-Thunk 所做的一切。然而,Redux-Thunk 做得非常好的一件事是手动调度一个动作。这是关键部分。使用 Redux-Thunk,我们可以在未来的某个时间点手动调度操作。
所以我们创建了这个新动作,它可以是一个普通的 JavaScript 对象或函数,但是当我们在 Redux-Thunk 或函数内部手动调度它时,它基本上总是一个普通的对象。
所以我们将调度这个动作,它会流回调度,调度将它直接发送回 Redux-Thunk,Redux-Thunk 会询问它是一个动作还是一个对象。
当它是一个对象时,Redux-Thunk 会自动将它转发给所有不同的 reducer。
使用 Redux-Thunk,我们可以返回一个函数,如果我们这样做了,该函数将使用 dispatch 和 getState 参数调用,通过这两个函数,我们对 Redux 存储拥有无限的权力,我们可以更改任何数据和读取任何数据,并且在未来的任何时间点,我们都可以手动调度操作并更新我们商店中的数据。
我在哪里获得dispatch 和getState?来自 Redux-Thunk 库源代码:
https://github.com/reduxjs/redux-thunk/blob/master/src/index.js
src/index.js:
function createThunkMiddleware(extraArgument) {
return ({ dispatch, getState }) => next => action => {
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
return next(action);
};
}
const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;
export default thunk;
如果您查看 if 条件,您会看到正在发生的实际逻辑的主体。你刚刚发送了一个动作吗?如果是这样,它是一个函数吗?如果是,那么 Redux Thunk 将使用 dispatch 和 getState 调用该操作。
如果我们的动作不是一个函数,Redux-Thunk 不关心它,所以它会转到return next(action); 指示的下一个中间件,否则如果没有中间件可运行,则转到减速器。