乐闻世界logo
搜索文章和话题

React 状态管理 redux-thunk 和 redux-promise 有什么区别?

7 个月前提问
3 个月前修改
浏览次数44

4个答案

1
2
3
4

Redux-thunk 和 redux-promise 都是用于在 Redux 状态管理库中处理异步操作的中间件,但它们在处理异步动作时的方式存在差异。以下是它们各自的特点和区别:

Redux-thunk

特点:

  • Redux-thunk 是一个中间件,允许我们在 action creators 里面创建返回函数而不是返回 action 对象的能力。
  • 这个返回的函数接收 dispatchgetState 作为参数,可以执行异步操作,并且在操作完成后手动调用 dispatch
  • Thunk 是一个允许我们写更多复杂异步逻辑的工具,包括序列化的异步调用、延迟异步调用等。

例子:

javascript
// Action creator 返回一个函数(thunk) export const fetchData = () => { return (dispatch, getState) => { dispatch({ type: 'FETCH_DATA_REQUEST' }); return fetch('/my-api-endpoint') .then(response => response.json()) .then(data => dispatch({ type: 'FETCH_DATA_SUCCESS', payload: data })) .catch(error => dispatch({ type: 'FETCH_DATA_FAILURE', error })); }; };

在上面的例子中,fetchData 函数不是返回一个 action 对象,而是返回一个函数。这个函数可以执行异步请求并在请求完成后通过 dispatch 发送一个新的 action。

Redux-promise

特点:

  • Redux-promise 是另一种 Redux 异步中间件,它专注于处理返回 promise 对象的 action。
  • 当一个 action creator 返回一个 promise 时,redux-promise 中间件会等待这个 promise 解决,并且自动发送一个带有解决值的 action 或者在 promise 被拒绝时发送一个带有错误信息的 action。

例子:

javascript
// Action creator 返回一个携带 promise 的 action 对象 export function fetchData() { return { type: 'FETCH_DATA', payload: fetch('/my-api-endpoint').then(response => response.json()) }; };

在这个例子中,fetchData 函数返回一个包含 typepayload 的 action 对象。 payload 是一个 promise,由 redux-promise 自动处理。

区别

  1. 返回值:

    • Redux-thunk 允许 action creators 返回函数(thunk),这些函数可以执行任何异步逻辑并调用 dispatch
    • Redux-promise 要求 action creators 返回一个 promise 作为 payload 的 action 对象。
  2. 复杂异步流程控制:

    • Redux-thunk 可以实现更复杂的异步流程控制,如条件分支、延迟异步调用、连续异步调用等。
    • Redux-promise 对异步控制的支持较为简单,主要是针对单一的异步操作。
  3. 易用性:

    • Redux-thunk 提供的灵活性更高,但是需要开发者手动处理 dispatch。
    • Redux-promise 使用起来更简单,只需返回 promise 即可,但它的灵活性不如 thunk。

综上所述,redux-thunk 提供了对异步操作更精细和复杂控制的能力,而 redux-promise 则提供了一种简洁的处理异步请求的方式,适用于更简单的场景。开发者可以根据实际项目需求选择最合适的工具。

2024年6月29日 12:07 回复

redux-thunk允许您的动作创建者返回一个函数:

shell
function myAction(payload){ return function(dispatch){ // use dispatch as you please } }

redux-promise允许他们返回一个承诺:

shell
function myAction(payload){ return new Promise(function(resolve, reject){ resolve(someData); // redux-promise will dispatch someData }); }

如果您需要异步或有条件地分派操作,这两个库都很有用。redux-thunk还允许您在一个动作创建器中多次调度。无论您选择其中之一、另一个还是两者都完全取决于您的需求/风格。

2024年6月29日 12:07 回复

您可能希望/需要在您的应用程序中同时使用两者。从 redux-promise 开始用于常规的 Promise 生成异步任务,然后随着复杂性的增加而扩展以添加 Thunk(或 Sagas 等)

  • 当生活很简单时,您只需与返回单个承诺的创建者进行基本的异步工作,然后redux-promise将改善您的生活并简化它,快速而轻松。(简而言之,当你的 Promise 解决时,你不需要考虑“拆开”它们,然后编写/发送结果,redux-promise(-middleware) 会为你处理所有那些无聊的事情。)
  • 但是,当出现以下情况时,生活会变得更加复杂:
  • 也许你的动作创建者想要产生几个承诺,你想将它们作为单独的动作分派到单独的减速器?
  • 或者,在决定如何以及在何处分派结果之前,您需要管理一些复杂的预处理和条件逻辑?

在这些情况下,它的好处redux-thunk是它允许您将复杂性封装在 action-creator 中

但请注意,如果您的 Thunk 生成并分派 Promise,那么您将需要同时使用这两个库

  • Thunk 将编写原始操作并分派它们
  • redux-promise然后将在减速器处处理由 Thunk 生成的各个 Promise 的解包,以避免产生样板文件。(你_可以_用 Thunks 做所有事情,promise.then(unwrapAndDispatchResult).catch(unwrapAndDispatchError)但为什么要这么做呢?)

总结用例差异的另一种简单方法:Redux 操作周期的开始与结束

  • Thunk 用于Redux 流程的_开始_:如果您需要创建一个复杂的操作,或者封装一些粗糙的操作创建逻辑,将其排除在组件之外,并且绝对排除在减速器之外。
  • redux-promise是在流程_结束时_,一旦所有内容都归结为简单的承诺,并且您只想打开它们并将其已解决/拒绝的值存储在商店中

注释/参考文献:

  • 我发现redux-promise-middleware这是对原始想法的更完整和更容易理解的实现redux-promise。它正在积极开发中,并且也得到了很好的补充redux-promise-reducer
  • 还有其他类似的中间件可用于组合/排序复杂的操作:一种非常流行的中间件是redux-saga,它与 非常相似redux-thunk,但基于生成器函数的语法。同样,您可能会将它与 结合使用redux-promise,因为 sagas Produce 承诺您不希望使用大量样板手动打开和处理...
  • 这是一篇很棒的文章,直接比较了各种异步组合选项,包括 thunk 和 redux-promise-middleware。(TL;DR:“与其他一些选项相比,Redux Promise 中间件极大地减少了样板代码” …… “我想我喜欢 Saga 来处理更复杂的应用程序(阅读:“使用”),而 Redux Promise 中间件则适合其他一切。”
  • 请注意,有一个重要的情况,您可能认为需要分派多个操作,但实际上不需要,并且您可以使简单的事情变得简单。这就是您只希望多个减速器对单个异步调用做出反应的地方,并且您倾向于向这些多个减速器分派多个操作。但是,_多个减速器完全没有理由不能监视单个操作类型。_您只想确保您的团队知道您正在使用该约定,因此他们不会假设只有一个减速器(具有相关名称)可以处理给定的操作。
2024年6月29日 12:07 回复

全面披露:我对 Redux 开发相对较新,并且自己也为这个问题而苦苦挣扎。我将解释我找到的最简洁的答案:

当调度操作时,ReduxPromise 返回一个 Promise 作为有效负载,然后 ReduxPromise 中间件解析该 Promise 并将结果传递给减速器。

另一方面,ReduxThunk 强制操作创建者推迟实际将操作对象分派给减速器,直到调用分派为止。

这是我找到此信息的教程的链接: https: //blog.tighten.co/react-101-part-4-firebase

2024年6月29日 12:07 回复

你的答案