我有一个具有这种结构的 React 钩子。我想要做的是,在完成调用 getUserJoinedSlotList()
并获得结果后,然后我想调用 getAllAvailableSlot()
都将结果设置到 useState
挂钩中。
const [joinedSlotList, setJoinedSlotList] = useState(null)
const [availableSlotList, setAvailableSlotList] = useState(null)
const [isAllSlotLoading, setIsAllSlotLoading] = useState(true)
const getJoinedList = () => {
getUserJoinedSlotList()
.then(res => {
setIsLoading(false)
setJoinedSlotList(res.joined_slot)
})
.catch(error => {
setIsLoading(false)
setErrorMsg(error.message)
})
}
const getAvailableSlotList = () => {
getAllAvailableSlot()
.then(res => {
setIsAllSlotLoading(false) // this setting not working, at the 2nd API call
setAllAvailableSlotList(res.slot)
})
.catch(error => {
setAvailableErrMsg(error.message)
setIsAllSlotLoading(false)
})
}
useEffect(() => {
if (user !== null) {
getJoinedList()
}
}, [user])
这是 getAvailableSlot() 的代码,我使用的是 Aws 放大,因此它实际上返回了 GET
请求的承诺
import { API } from 'aws-amplify';
export const getAllAvailableSlot = async () => {
let path2 = path + '/list_all'
return API.get(apiName, path2)
}
我的尝试:
放入getAvailableSlotList
作为getJoinedList()
的回调函数,如下:
const getJoinedList = (callback) => {
getUserJoinedSlotList()
.then(res => {
setIsLoading(false)
setJoinedSlotList(res.joined_slot)
})
.catch(error => {
setIsLoading(false)
setErrorMsg(error.message)
})
callback()
}
then
useEffect(() => {
if (user !== null) {
getJoinedList(getAvailableSlotList) // put in as call back here
}
}, [user])
这样,getAllAvailableSlot
被调用,我得到了结果。但是调用setAvailableSlotList
后没有设置结果,setIsAllSlotLoading(false)
也不能正常工作,仍然true
然后我试着这样打电话:
const getJoinedList = () => {
getUserJoinedSlotList()
.then(res => {
setIsLoading(false)
setJoinedSlotList(res.joined_slot)
getAvailableSlotList() // here call the function
})
.catch(error => {
setIsLoading(false)
setErrorMsg(error.message)
})
}
再次,结果与上述尝试相同。
然后我也这样尝试:
const calling = async () => {
await getJoinedList()
await getAvailableSlotList() //setAvailableSlotList and setAllIsLoading is not working, the 2ND CALL
}
useEffect(() => {
if (user !== null) {
//getJoinedList()
calling()
}
}, [user])
但是 getAvailableSlotList()
设置的钩子仍然没有任何效果。
具体问题:
我注意到,第二个 API 调用是成功的,但是我调用的用于设置钩子的后续函数却没有任何效果。
意味着:
getJoinedList()
中的所有内容都运行良好。但是当到达 getAvailableSlotList()
时,我可以从中获取 API 结果,但是 setAvailableSlotList
和 setIsAllSlotLoading
都无法在值中设置
问题:
1 个 API 调用完成后如何调用另一个 API?
如何在第二次 API 调用时设置 React 钩子?
答案 0 :(得分:1)
您的第二次尝试应该会成功。这是一个简化的沙箱示例:https://codesandbox.io/s/romantic-bhaskara-odw6i?file=/src/App.js
关于第一次和第三次尝试出错的地方的一些解释:
第一次尝试就快完成了,只是您需要将 callback()
移到 .then()
块内,这实际上会将您带到第二次尝试。
第三个您使用了 async/await 但问题不是 getJoinedList()
也不是 getAvailableSlotList()
返回 Promise
,因此两个请求将大约在同一时间发送,而不会等待另一个先解决。
答案 1 :(得分:0)
最简单的解决方案实际上是通过链接将整个 getAllAvailableSlot() 函数添加到 getUserJoinedSlotList() 中。我看到你已经在使用它了,所以我不需要深入解释。
getUserJoinedSlotList().then(res => {
--- logic ---
getAllAvailableSlot().then(res2 => {
-- logic ---
}
}
答案 2 :(得分:0)
然后链接及其配对可以在这里工作。
await getUserJoinedSlotList()
.then(res => /*assign hooks data*/)
.then(() => getAllAvailableSlot())
.then(availableSlot => /*assign availableSlot data*/)
.catch(e => console.log(e))