>我有 2 个不同的组件需要执行相同类型的编排:
useEffect(() => {
async function fetchData() {
if (route.params['id']) {
const resConversation = await axios(`...`)
setConversationState({ ...conversationState, currentConversation: resConversation.data })
const resParticipants = await axios(`...`)
setParticipants(resParticipants.data)
const resStream = await axios(`somestuff`)
setAudioState({ ...audioState, ...resStream })
}
}
fetchData()
}, [])
setAudioState
和setConversationState
来自useContext
。
对我来说,这样做并保持代码干燥的最佳方法是什么?
我想过一个自定义useGetConversation
钩子,但我只能在我的组件函数体中调用它。有没有更好的方法?
如果调用不相互依赖,请使用Promise.all()
进行并行调用,解构响应,然后设置它们。
我还可以通过使用 reducer 通过useReducer
设置状态来避免多次设置调用。
useEffect(() => {
if (!route.params['id']) {
return
}
async function fetchData() {
const [resConversation, resParticipants, resStream] = await Promise.a([
axios(`...`),
axios(`...`),
axios(`somestuff`)
]);
setConversationState(conversationState => ({ ...conversationState, currentConversation: resConversation.data }))
setParticipants(resParticipants.data)
setAudioState(audioState => ({ ...audioState, ...resStream }))
}
fetchData()
}, [])
如果调用相互依赖,请先进行调用,然后再设置状态:
useEffect(() => {
if (route.params['id']) {
return
}
async function fetchData() {
const resConversation = await axios(`...`)
const resParticipants = await axios(`...`)
const resStream = await axios(`somestuff`)
setConversationState(conversationState => ({ ...conversationState, currentConversation: resConversation.data }))
setParticipants(resParticipants.data)
setAudioState(audioState => ({ ...audioState, ...resStream }))
}
fetchData()
}, [])
您还可以将调用 API 并将状态设置为单个函数捆绑在一起,但这对我来说似乎有点不可读:
const callAndSet = async (axiosRequest, setter) => {
const res = await axios(axiosRequest)
setter(res)
}
useEffect(() => {
if (!route.params['id']) {
return
}
async function fetchData() {
await callAndSet(`...`, resConversation => setConversationState(conversationState => ({ ...conversationState, currentConversation: resConversation.data })))
await callAndSet(`...`, resParticipants => setParticipants(resParticipants.data))
await callAndSet(`somestuff`, resStream => setAudioState(audioState => ({ ...audioState, ...resStream })))
}
fetchData()
}, [])