简体   繁体   English

在 React / Redux 和 redux-thunk 中,如果在 fn 是 thunk 时调用 fn()(dispatch) 会发生什么?

[英]In React / Redux and redux-thunk, what happens if fn()(dispatch) is called when fn is a thunk?

I am new to a React project code base, and I saw one function:我是 React 项目代码库的新手,我看到了一个 function:

const fn = foo => dispatch => { 
  // do something
}

so fn is a function that takes foo and returns a function that takes dispatch and does something.所以fn是一个 function ,它接受foo并返回一个 function ,它接受dispatch并做一些事情。

So inside of fn , I wanted to do some smaller tasks, and would call itself to accomplish that, so I had:所以在fn内部,我想做一些较小的任务,并且会调用自己来完成它,所以我有:

// Code sample 01:

const fn = foo => dispatch => { 
  // do something

  if (someCondition) {
    fn(123)(dispatch);
  }
}

My coworker told me fn is actually used as part of redux-thunk (and so I think fn is a thunk), and the proper way is to call it as:我的同事告诉我fn实际上是用作 redux-thunk 的一部分(所以我认为fn是一个 thunk),正确的方法是将其称为:

// Code sample 02:

const fn = foo => dispatch => { 
  // do something

  if (someCondition) {
    dispatch(fn(123));
  }
}

But I wonder if I use Code Sample 01 above, it seemed to run, but the processor has half of the 12 cores running at 80% capacity after the code has run to finish.但是我想知道如果我使用上面的代码示例 01,它似乎可以运行,但是在代码运行完成后,处理器有 12 个内核中的一半以 80% 的容量运行。 It sometimes even cause the whole tab of Google Chrome to become unresponsive.有时甚至会导致 Google Chrome 的整个标签页变得无响应。 What is the reason that Code Sample 01 causes that / what really is happening?代码示例 01 导致这种情况的原因是什么/真正发生了什么?

redux is synchronous. redux 是同步的。 in order to be able to do some async action before dispatch, you can use some libraries like redux-thunk .为了能够在调度之前执行一些异步操作,您可以使用一些库,例如redux-thunk

redux-thunk intercepts your action creator function. redux-thunk拦截你的动作创建者 function。 if your function returns another function than redux-thunk it will allow you to do some async action, passing dispatch as params, so you can dispatch once you resolve your async request.如果您的 function 返回另一个 function 而不是redux-thunk它将允许您执行一些异步操作,将调度作为参数传递,因此您可以在解决异步请求后调度。

on the other hand, if the function doesnt return another function, redux-thunk will let dispatch call the reducers right away as synchronous.另一方面,如果 function 没有返回另一个 function, redux-thunk会让 dispatch 立即同步调用 reducer。

the proper way to use redux-thunk would call dispatch after some async action in a promise chain or an async await fashion:使用redux-thunk的正确方法是在 promise 链或异步等待方式中的一些异步操作之后调用调度:

const myAsyncAction = foo => dispatch => { 
  // do something async like
  // promise chain example but you could use async await
  axios.get('myUrl')
    .then(res => dispatch({ action: 'loaded', payload: res}))
    .catch.(err => dispatch({action: 'fail', payload: err}))
  }
}

I think fn is a thunk我认为fn是一个 thunk

fn here is better described as a 'thunk creator' - the thunk is actually the function taking dispatch as an argument - ie what fn returns.这里的fn被更好地描述为“thunk 创建者” - thunk 实际上是 function 以dispatch作为参数 - 即fn返回的内容。

Your example here is really interesting - I've never seen a thunk recursively dispatch itself, but since a thunk literally is just a function taking dispatch as an argument, I see both styles as equally valid.你在这里的例子真的很有趣 - 我从来没有见过一个 thunk 递归地调度自己,但由于 thunk 实际上只是一个 function 以dispatch作为参数,我认为 styles 都同样有效。

When you dispatch a thunk, the dispatch argument that gets injected into the thunk comes from the redux-thunk middleware.当你调度一个 thunk 时,注入到 thunk 中的dispatch参数来自redux-thunk中间件。 Thecode for this middleware is really simple - there is no magic going on here at all. 这个中间件的代码非常简单——这里根本没有魔法。

The dispatch injected into the thunk by the middleware is the same dispatch you use have available anywhere else via redux, and it's just a synchronous JS function call.中间件注入到 thunk 的dispatch与您使用的dispatch相同,您可以通过 redux 在其他任何地方使用,它只是一个同步的 JS function 调用。 Therefore, fn(123)(dispatch) is literally the same as doing dispatch(fn(123)) .因此, fn(123)(dispatch)在字面上与dispatch(fn(123))相同。 When you do it the second way, it actually just results in the first way being called but inside the middleware instead of just directly.当您以第二种方式执行此操作时,它实际上只会导致第一种方式被调用,但在中间件内部而不是直接调用。

Because of that, the two code examples you've given are functionally equivalent, and they should have exactly the same behaviour.因此,您给出的两个代码示例在功能上是等效的,并且它们应该具有完全相同的行为。 I'm not sure what's causing the performance issue with the first example, but it must be some other bug inside the // do something section or elsewhere that's different between the two.我不确定是什么导致了第一个示例的性能问题,但它一定是在// do something部分或其他地方的一些其他错误,这两者之间是不同的。 From a 'redux perspective', both approach 1 and approach 2 are completely valid and equivalent.从“redux 角度”来看,方法 1 和方法 2 都是完全有效且等效的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM