redux thunk 如何调用 curried async thunk 函数?

How redux thunk calls curried async thunk functions?

如果 Whosebug 上有类似的问题,我深表歉意,但经过 3 小时的搜索,我找不到。

我正在尝试学习 Redux 并精通 ReactJS 并拥有以下 thunk 功能:

export const listProducts = () => async (dispatch) => {
try{
    dispatch({ type:PRODUCT_LIST_REQUEST })
    const { data } = await axios.get('/api/products/') 
    dispatch({ type:PRODUCT_LIST_SUCCESS, payload: data })

}catch(error){
    dispatch({
        type:PRODUCT_LIST_FAIL,
        payload: misc_data_here
    })
}}

此函数在 dispatch 函数中的另一个文件中调用,相关代码如下:

function HomeScreen() {

const dispatch = useDispatch()
const productList = useSelector(state => state.productList)
const { error, loading, products } = productList

useEffect(() => {
    dispatch(listProducts())
    
}, [dispatch])

return (rest of UI...]

我的问题如下:

在这种情况下,listProducts 究竟是如何被 redux 调用的?如果我的(可怜的)理解是正确的,它需要被称为 listProducts()(dispatch function here) 。 thunk (async (dispatch)) 究竟是如何被馈送到调度函数的,以及 listProducts 函数实际返回到 HomeScreen() 中的 dispatch 调用中的内容?

Redux 不会调用你的 listProducts 动作创建者,你会在你发送动作时调用。 thunk redux 中间件检查 action 值是否是一个对象,即像一个普通的 action 对象,还是一个函数。如果它是一个函数,那么中间件会调用 curried 函数并传递 dispatchgetState 函数,以便处理异步逻辑并可以调度任何进一步的操作。

How does the middleware work?

The actual implementation of the thunk middleware is very short - only about 10 lines. Here's the source, with additional added comments:

Redux thunk middleware implementation, annotated

// standard middleware definition, with 3 nested functions:
// 1) Accepts `{dispatch, getState}`
// 2) Accepts `next`
// 3) Accepts `action`
const thunkMiddleware =
  ({ dispatch, getState }) =>
  next =>
  action => {
    // If the "action" is actually a function instead...
    if (typeof action === 'function') {
      // then call the function and pass `dispatch` and `getState` as arguments
      return action(dispatch, getState)
    }

    // Otherwise, it's a normal action - send it onwards
    return next(action)
  }

In other words:

  • If you pass a function into dispatch, the thunk middleware sees that it's a function instead of an action object, intercepts it, and calls that function with (dispatch, getState) as its arguments
  • If it's a normal action object (or anything else), it's forwarded to the next middleware in the chain

See also the Redux Async data flow 以获得出色的动画视觉解释。