【问题标题】:What is the difference between Redux Thunk and Redux Saga?Redux Thunk 和 Redux Saga 有什么区别?
【发布时间】:2018-10-21 11:54:25
【问题描述】:

Redux Thunk 和 Redux Saga 都是 Redux 的中间件。两者有什么区别以及如何确定何时使用 Redux Thunk 或 Redux Saga?

【问题讨论】:

标签: reactjs redux react-redux


【解决方案1】:

Redux Thunk 和 Redux Saga 都负责处理副作用。 简单来说,应用于最常见的场景(异步函数,特别是 AJAX 调用)Thunk 允许 Promises” 来处理它们,Saga 使用生成器。 Thunk 使用简单,许多开发人员都熟悉 Promises,Saga/Generators 更强大,但你需要学习它们。 当 Promise 足够好时,Thunk 也是如此,当您定期处理更复杂的情况时,Saga 为您提供更好的工具。

例如,当您在路由/视图中启动 AJAX 调用然后用户移动到另一个时会发生什么?无论如何,你能安全地让减速器改变状态吗? Saga 使取消效果变得微不足道,Thunk 需要您照顾它,解决方案不能很好地扩展。

实际上,选择一个或另一个确实取决于(同义反复)项目。

要记住的一点是,这两个中间件可以共存,因此您可以从 Thunks 开始,并在需要时/如果需要时引入 Sagas(然后根据实际经验选择重构的方式/内容...一种解决方案特别适合“学习项目”、MVP 等) 一般来说,Sagas 更强大且更易于测试,但它们引入了许多新概念,如果您还在学习其他技术(尤其是 Redux),这可能会让人有点不知所措。

具体来说,在处理简单有效的 Redux 哲学(将动作(文字对象)馈入 reducer(纯函数))时,您可以使用更有限但易于掌握的 Thunk 处理副作用(Promise.then( ).error()),或者 Saga 需要你面对(强大的)概念,即你可以用这些动作做更复杂的事情。

还值得一提的是 (redux-)observable 作为一种更复杂(甚至更强大)的范式来处理副作用,以防万一你熟悉它(如果你已经熟悉它,它可能更容易使用比学习 Saga)。

【讨论】:

    【解决方案2】:

    其实两者都是Redux处理异步动作的中间件。想知道then之间的区别,请注意下图:

    中间件盒通常是指将现有软件中的不同功能粘合在一起的软件服务。对于 Redux,中间件在分派一个动作和将动作交给 reducer 之间提供了一个第三方扩展点。然后reducer创建新的状态。

    Redux Thunk 是一个中间件,可让您调用返回函数而不是动作对象的动作创建者。该函数接收 store 的 dispatch 方法,然后在异步操作完成后用于在函数体内调度常规同步操作。 352B 体积,简单易学易用

    Redux Saga 利用称为GeneratorsES6 功能,允许我们编写看起来是同步的并且非常容易测试的异步代码。在 saga 中,我们可以轻松地测试我们的异步流程,并且我们的操作保持纯净。 复杂,难以学习和理解,14kB 的体积,但很容易组织复杂的异步操作,并且非常易读,并且 saga 有许多有用的工具来处理异步操作

    提示:如果您无法理解它们之间的区别或无法理解redux-saga 流程,但仍希望拥有可读的代码并避免回调地狱,请使用async/await 跟踪redux-thunk,我给offer举个例子:

    // simple usage of redux-thunk:
    export const asyncApiCall = values => {
      return dispatch => {
        return axios.get(url)
          .then(response =>{
            dispatch(successHandle(response));
          })
          .catch(error => {
            dispatch(errorHandle(error));
          });
        };
      };
    
    
    
    // async/await usage of redux-thunk:
    export const asyncApiCall = values => {
      return async dispatch => {
        try {
          const response = await axios.get(url);
          dispatch(successHandle(response));
        }
        catch(error) {
          dispatch(errorHandle(error));
        }
      };
    };
    

    【讨论】:

      猜你喜欢
      • 2016-08-03
      • 2016-11-19
      • 1970-01-01
      • 2017-05-28
      • 2019-06-15
      • 2017-04-26
      • 1970-01-01
      • 2021-09-23
      • 2016-08-26
      相关资源
      最近更新 更多