异步/等待redux thunk无法正确返回操作承诺

时间:2018-11-15 17:28:23

标签: reactjs express redux sequelize.js

我使用Axios遇到了麻烦,正在使用Sequelize发布到Express路由。

该路由已正确发布(即,数据已添加到数据库中),但是React组件内部的操作未按预期方式运行。使用async/await,我希望操作可以等到完成数据库发布后再继续,但这不是这种情况。我从这次行动中得到了undefined

暴徒击中了一条快速路线,在该路线上,我调度动作来更新我的redux存储并返回响应:

const addedNewList = (newList) => ({type: ADD_NEW_LIST, newList})

export const addNewList = (name, userId) => async dispatch => {
  try {
    const { data } = await axios.post('/api/list/add', { name, userId })
    dispatch(addedNewList(data))
    return data
  } catch (err) {
    console.error(err)
  }
}

使用调试器,我可以确认return data实际上正在从我需要的服务器返回响应。我还可以确认redux存储正在正确更新。

但是在这里,当我尝试以result的身份访问该响应数据时,我得到了undefined

  handleSubmit = async () => {
    const result = await this.props.addNewList(this.state.name, this.props.userId)

    // ** result is 'undefined' **

    this.handleClose()

    // pass off the results
  }

如果我在唤起setTimeout动作后添加addNewList,它会按预期工作。这向我暗示也许没有兑现承诺?但是我的理解是,如果您从thunk中返回服务器的响应,它将做到这一点。

为完整起见,这是我的路线,我也已通过调试器确认正在按预期方式传递数据:

const userAuth = function(req, res, next) {
  if (req.isAuthenticated()) {
    return next()
  }
  res.status(401).send('Unauthorized user')
}

router.post('/add', userAuth, async (req, res, next) => {
  const { name, userId } = req.body
  try {
    const list = await List.create({ name, userId })
    res.json(list)
  } catch(err) { next(err) }
})

为什么动作在undefined方法中返回handleSubmit

2 个答案:

答案 0 :(得分:0)

尝试返回dispatch中的addedNewList(data)

export const addNewList = (name, userId) => async dispatch => {
  try {
    const { data } = await axios.post('/api/list/add', { name, userId })
    return Promise.resolve(dispatch(addedNewList(data)));
  } catch (err) {
    console.error(err)
  }
}

话虽这么说,您可以考虑重组组件以改用mapStateToProps来使用更新后的Redux存储中的值/ result,而不是显式地等待响应并手动传递值?

答案 1 :(得分:0)

亚历山大(Alexander)的回应使我走上了正确的道路,因此,我分享了我的解决方案,以防它对某人有所帮助(按照他的建议)。

尽管我可以继续通过将分发内容包装在Promise中来尝试解决此问题,但更好的解决方案是重新考虑组件的结构。

在我的情况下,我想获取数据库中新创建的行的ID,以便可以将其传递到history.push

  handleSubmit = async () => {
    const result = await this.props.addNewList(this.state.name, this.props.userId)

    this.handleClose()

    history.push(`/list/${result.id}`)
}

result返回undefined的情况下,该网址未正确更新。

更好的解决方案是从redux存储中更新的地方访问新数据。这样,我可以确定直到数据准备就绪,历史记​​录才会更新。

所以我的更新组件现在看起来像这样,直到有newId可用时历史记录才更新:

  handleSubmit = () => {
    this.props.addNewList(this.state.name, this.props.userId)
    this.handleClose()
  }

  render(){
    const { newId } = this.props

    if (newId) { 
      history.push(`/list/${newId}`)
    }

   return (
      ....
   )
  }
}

const mapStateToProps = (state) => {
  return {
    newId: state.list.newId
  }
}

除了将其投入渲染之外,我可能还可以使用诸如componentWillReceiveProps之类的组件生命周期方法。

相关问题