我使用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
?
答案 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
之类的组件生命周期方法。