为什么要使用Redux Thunk

时间:2017-10-31 08:58:52

标签: reactjs react-redux redux-thunk

为什么要使用Redux Thunk然后可以做这样的事情:

ReadableAPI.getCategories().then((categories)=>{
      console.log('after getCategories', categories)

      this.props.dispatch(addCategories(categories))
    })

这不是更直截了当并且达到同样的目的吗?

3 个答案:

答案 0 :(得分:3)

丹·阿布拉莫夫(Dan Abramov)的答案很好地解释了为什么你想在你的应用程序中使用redux-thunk。在您的应用程序中使用redux-thunk的另一个好处是,您可以将业务逻辑与视图部分分开(在您的情况下为React)。我们有一个用例,我们的应用程序是用backbone编写的,我们想在React中重写整个应用程序。我们意识到,如果您的视图和集合/模型是分开的,那么很容易。我们开始仅对html模板进行折旧,而不是对集合进行折旧。当我们弃用所有html模板时,我们开始在我们的应用中使用Redux并弃用我们的收藏品。

我想在这里说的是我们将viewbusiness逻辑分开,我们可以轻松地重构它。同样地,对于ReactRedux,您可能希望保持不同,以便如果出现新内容并替换Redux,至少您不必弃用您的观看次数只需要改变你的业务逻辑。

答案 1 :(得分:0)

Redux Thunk 基本上允许我们延迟一个动作的发送,即我们可以处理动作创建者返回的动作,并在我们真正想要发送时调用dispatch函数。

答案 2 :(得分:0)

您的示例是不完整的,因此无法遵循您如何找到这个过于简化的解决方案。经过研究后,我意识到,您可能应该在某个位置放一个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包含任何数据?

所以我们只说所有问题的答案都是肯定的。

要处理异步请求,您会遇到一些困难,因为它不仅包含这段代码,而且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的情况下,您的动作创建者可以返回一个动作对象。如果您返回一个动作对象,它仍然必须具有type属性,并且如果它是一个返回的动作对象,则还可以选择具有有效负载。

Redux-Thunk所做的另一件事是允许您返回操作对象或函数。

如果您返回一个函数,则Redux-Thunk将自动为您调用该函数。

就这样,这就是Redux-Thunk所做的一切。但是,Redux-Thunk确实做得很好的一件事是手动调度一个动作。那是关键部分。借助Redux-Thunk,我们可以在将来的某个时间点手动调度操作。

因此,我们创建了这个新动作,它可以是普通的JavaScript对象或函数,但是当我们在Redux-Thunk内或函数内部手动分派它时,它基本上总是一个普通对象。 / p>

因此,我们将分派此操作,它会流回到分派中,然后分派将其直接发送回Redux-Thunk中,而Redux-Thunk将询问其操作或对象。

当Redux-Thunk作为对象时,会自动将其转发给所有不同的reducer。

使用Redux-Thunk,我们可以返回一个函数,如果这样做,该函数将被dispatchgetState参数调用,并且使用这两个函数,我们可以对Redux存储拥有无限的权力,我们可以更改任何数据并读取任何数据,并且在将来的任何时间点,我们都可以手动调度操作并更新商店中的数据。

我在哪里得到dispatchgetState?从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将使用dispatchgetState来调用该动作。

如果我们的操作不是一个函数,则Redux-Thunk不会在意它,因此它将继续运行到return next(action);所指示的下一个中间件,否则,如果没有可运行的中间件,则将其转到化简器