usereducer 异步_使用useReducer进行异步操作

本文翻译自《async-actions-with-usereducer-d75a2c5dc55c》,探讨如何在JavaScript中利用useReducer Hook进行异步操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

usereducer 异步

React’s useReducer brings us one step closer to replacing ReduxStore with basic react hooks. Now creating a store and dispatch function is as easy as calling useReducer with your reducer function and initial state object.

React的useReducer使我们比用基本的React钩子替换ReduxStore更近了一步。 现在,创建存储和调度函数就像使用reducer函数和初始状态对象调用useReducer一样容易。

const [state, dispatch] = useReducer(reducer, initialState)

But what about async actions? Redux allows you to pass functions to your dispatch that will be invoked with your dispatch object.

但是异步动作呢? Redux允许您将函数传递给调度 ,该函数将与调度对象一起调用。

dispatch((dispatch) => {
someAsyncOperation((result) => {
dispatch({ type: 'UPDATE_RESULT', payload: result })
}
})

You can use the thunk pattern to if you’d like to pass arguments to your async operation.

如果要将参数传递给异步操作,则可以使用thunk模式

function thunk(someArg: string) {
return function(dispatch: Dispatch<ActionType>) {
someAsyncOperation(someArg, (result) => {
dispatch({ type: 'UPDATE_RESULT', payload: result })
}
}
}dispatch(thunk("foo"))

It’s a nice pattern, but it doesn’t work with the out-of-the-box dispatch we get with useReducer. So how do we achieve the same effect without Redux?

这是一个很好的模式,但不适用于我们通过useReducer获得的现成的分派。 那么,如何在没有Redux的情况下实现相同的效果?

Let’s keep it simple. Use a utility function like this.

让我们保持简单。 使用这样的实用程序功能。

Pass the original dispatch returned from useReducer into our wrapAsync utility function. It will return a function that serves as a proxy for the original dispatch and invokes the dispatched action if it happens to be a function. The T generic here is inferred from the action type of your dispatch. Here’s how it looks in action:

useReducer返回的原始调度useReducer到我们的wrapAsync实用程序函数中。 它将返回一个充当原始调度的代理的函数,并在恰好是一个函数的情况下调用调度的动作。 这里的T泛型是根据调度的操作类型推断的。 实际效果如下:

const [state, dispatch] = useReducer(reducer, initialState)
const asyncDispatch = wrapAsync(dispatch)asyncDispatch((dispatch) => dispatch({ /* Action */ }))

But wait- one last thing. We’re currently generating a new wrapped dispatch object on every render but we shouldn’t need to call wrapAsync() again unless the original dispatch object returned from useReducer changes. We’ll use another basic react hook for this:

但是,等等-最后一件事。 当前,我们在每个渲染器上都生成一个新的包装的分发对象,但是除非从useReducer返回的原始分发对象发生更改,否则我们无需再次调用wrapAsync() 。 我们将为此使用另一个基本的react钩子:

const [state, dispatch] = useReducer(reducer, initialState)
const asyncDispatch = useMemo(() => wrapAsync(dispatch), [dispatch])

The dependency array in useMemo here ensures that we only need to call wrapAsync if the original dispatch changes.

此处useMemo的依赖关系数组可确保仅在原始调度发生更改时才需要调用wrapAsync。

That’s it. You could of course extract this into a custom useAsyncReducer hook if you wanted to- but that’s up to you. You could also use a promise version of the async dispatch, here’s a promise version of the util function. Hope this helps!

而已。 当然,如果愿意,您可以将其提取到自定义useAsyncReducer挂钩中,但这取决于您。 您还可以使用异步调度的Promise版本,这是util函数的Promise版本。 希望这可以帮助!

type AsyncDispatch<T> = Dispatch<T | Promise<T>>


function wrapAsync<T>(dispatch: Dispatch<T>): AsyncDispatch<T> {
  return (action: T | Promise<T>) => {
    if (action instanceof Promise) {
      return action.then(dispatch)
    }
    return dispatch(action)
  }
}

翻译自: https://medium.com/@joseph.michael.sample/async-actions-with-usereducer-d75a2c5dc55c

usereducer 异步

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值