使用redux saga时,请等待redux操作完成调度

时间:2018-11-22 13:05:07

标签: reactjs redux redux-saga

我有一个redux saga设置,可以正常工作。我的调度之一是创建一个新订单,然后在创建新订单后,我要使用更新后的状态进行处理。

// this.props.userOrders = []

dispatch(actions.createOrder(object))

doSomethingWith(this.props.userOrders)

由于createOrder操作触发了调用API的redux传奇,因此存在延迟,因此在调用我的函数doSomethingWith之前不会更新this.props.userOrders。我可以设置一个超时时间,但这似乎不是一个可持续的想法。

我已经阅读了有关Stack Overflow的类似问题,并尝试实现了相关的方法,但是我似乎无法使其正常运行。我希望下面的代码可以有人添加几行来完成。

以下是其他相关文件:

actions.js

export const createUserOrder =(数据)=>({   类型:“ CREATE_USER_ORDER”,   数据 })

Sagas.js

function * createUserOrder () {
  yield takeEvery('CREATE_USER_ORDER', callCreateUserOrder)
}

export function * callCreateUserOrder (newUserOrderAction) {
  try {
    const data = newUserOrderAction.data
    const newUserOrder = yield call(api.createUserOrder, data)
    yield put({type: 'CREATE_USER_ORDER_SUCCEEDED', newUserOrder: newUserOrder})
  } catch (error) {
    yield put({type: 'CREATE_USER_ORDER_FAILED', error})
  }
}

Api.js

export const createUserOrder = (data) => new Promise((resolve, reject) => {
  api.post('/userOrders/', data, {headers: {'Content-Type': 'application/json'}})
    .then((response) => {
      if (!response.ok) {
        reject(response)
      } else {
        resolve(data)
      }
    })
})

减速机

case 'CREATE_USER_ORDER_SUCCEEDED':
   if (action.newUserOrder) {
      let newArray = state.slice()
      newArray.push(action.newUserOrder)
          return newArray
       } else {
       return state
   }

1 个答案:

答案 0 :(得分:1)

这感觉像是XY Problem。在任何时候,您都不应该在组件的生命周期函数/事件处理程序内部“等待”,而应该利用商店的当前状态。

如果我正确理解,这是您当前的流程:

  

您在React组件中调度了一个动作CREATE_USER_ORDER。您的callCreateUserOrder传奇消耗了该动作。当您的创建订单传奇完成时,它会分派另一个“已完成”操作,您已经以CREATE_USER_ORDER_SUCCEEDED的身份拥有该操作。

您现在应该添加的是处理CREATE_USER_ORDER_SUCCEEDED的适当的化简/选择器:

CREATE_USER_ORDER_SUCCEEDED动作应由您的reducer处理,以创建一个新状态,在该状态中填充您状态中的某些“ orders”属性。可以通过选择器将其直接连接到您的组件,这时将重新渲染您的组件并填充this.props.userOrders


示例:

组件

class OrderList extends React.PureComponent {
  static propTypes = {
    userOrders: PropTypes.array.isRequired,
    createOrder: PropTypes.func.isRequired,
  }

  addOrder() {
    this.props.createOrder({...})
  }

  render() {
    return (
      <Wrapper>
        <Button onClick={this.addOrder}>Add Order</Button>
        <List>{this.props.userOrders.map(order => <Item>{order.name}</Item>)}</List>
      </Wrapper>
    )
  }
}

const mapStateToProps = state => ({
  userOrders: state.get('userOrders'),
})

const mapDispatchToProps = {
  createOrder: () => ({ type: 'CREATE_ORDER', payload: {} }),
}

export default connect(mapStateToProps, mapDispatchToProps)(OrderList)

减速器

case 'CREATE_USER_ORDER_SUCCEEDED':
  return state.update('userOrders',
    orders => orders.concat([payload.newUserOrder])
  )

如果您确实确实需要副作用,则将这些副作用添加到您的传奇中,或创建一个采取SUCCESS动作的新传奇。