在 react redux saga 中处理同步
Posted
技术标签:
【中文标题】在 react redux saga 中处理同步【英文标题】:Handle Sync in react redux saga 【发布时间】:2019-03-03 15:06:39 【问题描述】:用户将输入姓名电子邮件和订单信息,包括付款详情。 在单击表单中的“立即购买”按钮时,我计划执行以下步骤:
通过 api 调用创建用户。 自动登录并通过以下方式获取令牌 api 调用。 使用表单数据通过api调用创建订单。 通过 api 调用获取支付提供商令牌。 进入付款页面。在前端使用 React-redux-saga。
请在下面的代码:
function* addToCartCamp(action)
try
// User creation and login
yield put( type: authActions.AUTH_REGISTER_REQUEST, ...createUser );
yield put( type: authActions.AUTH_REGISTER_SUCCESS, ...userdata );
yield put( type: authActions.AUTH_LOGIN_REQUEST, ...login );
//Create order
const data = yield orderAPI.addToCartCamp(action);
yield put( type: orderActions.ADD_TO_CART_SUCCESS, ...data );
yield put( type: orderActions.GET_DETAIL_ORDER_REQUEST, ...orderId: order_id );
//Handle Payment
if(action.payment.method === 'creditCard')
yield put( type: orderActions.TOKEN_REQUEST, ...orderId: order_id );
else
yield put( type: orderActions.BANK_TRANSFER_REQUEST, ...orderId: order_id );
catch (error)
// handle error message
我可以在 saga 文件中调用多个 Yield put,然后调用 api。调用此函数时,后端甚至在用户创建和登录之前就开始订单创建过程。
我需要所有进程同步运行,但它们当前以异步方式运行。
新的传奇和反应。怎么办?
【问题讨论】:
【参考方案1】:tl;dr:您需要take()
一个动作和call()
api 以在put()
成功动作之前产生其结果。
示例
function* addToCartCamp(action)
try
const action = yield take(authActions.AUTH_REGISTER_REQUEST);
const userToCreate = action.payload;
const userData = yield call(authApi.createUser, userToCreate);
yield put( type: authActions.AUTH_REGISTER_SUCCESS, userData );
const sessionData = yield call(authApi.loginUser, userData);
yield put( type: authActions.AUTH_LOGIN_SUCCESS, sessionData );
// ...
补充说明
在我看来,你在一个传奇中发生了太多事情。为什么要在创建订单的同一个地方注册用户?我会将这两个用例分成两个不同的 saga,因为您可能有一个已经注册的用户,只需要在购买之前登录。不要在您的订单传奇中处理身份验证,让 API 处理身份验证失败。
说到这里,你还应该有 api 调用失败的动作。因此,当服务器返回 401 时,因为用户无权购物,您应该 yield put
使用特定的 orderActions.SOMETHING_FAILURE
操作,其中包含存储错误消息、处理挂起状态等的减速器。
拥有全局 try catch 块会使调试变得非常困难,应该避免。见https://github.com/redux-saga/redux-saga/blob/master/docs/basics/ErrorHandling.md(最后一个代码示例):
import Api from './path/to/api'
import call, put from 'redux-saga/effects'
function fetchProductsApi()
return Api.fetch('/products')
.then(response => ( response ))
.catch(error => ( error ))
function* fetchProducts()
const response, error = yield call(fetchProductsApi)
if (response)
yield put( type: 'PRODUCTS_RECEIVED', products: response )
else
yield put( type: 'PRODUCTS_REQUEST_FAILED', error )
【讨论】:
感谢您的建议。我将帐户创建和登录移动到页面中的不同按钮操作,然后休息到不同的按钮操作。现在可以顺利运行,没有任何问题。 很高兴我能帮上忙。顺便说一句,如果我的回答解决了您的问题,您可以接受并投票赞成。以上是关于在 react redux saga 中处理同步的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 React 钩子处理/链接依赖于另一个的同步副作用
redux-saga的简单使用——saga的模块化拆分——saga进行网络请求——同步修改状态
redux-saga的简单使用——saga的模块化拆分——saga进行网络请求——同步修改状态