我有两个按钮显示不同的内容(消息和公告)
假设在初始挂载时调用API获取Message
列表,在用户从API获得响应之前,使用press
Announcement
按钮获取Announcement
列表。
这里我想取消Message
的API调用,并调用Announcement
API,
我试过这段代码,但没有结果:
import React from 'react';
import { ActivityIndicator, Dimensions, Text, TouchableOpacity, View } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import AxiosHTTP from '../../../Component/AxiosHTTP';
const {width, height} = Dimensions.get('window')
export default Notification = (props)=>{
const [data, setData] = React.useState(null)
const [activeIndex, setIndex] = React.useState(props.activeIndex || 0)
const source = React.useRef(null)
/**
* List function to handling component
*/
React.useEffect(()=>{
setData(null)
source.current = axios.CancelToken.source()
if(activeIndex == 0){
AxiosHTTP.get('http://httpstat.us/200?sleep=4000', {cancelToken: source.token})
.then(res=>{
setData(JSON.stringify(res.data))
})
} else {
AxiosHTTP.get('http://httpstat.us/200?sleep=4000', {cancelToken: source.token})
.then(res=>{
setData(JSON.stringify(res.data)+' Else')
})
}
}, [activeIndex])
function handleChangeTab(ind){
source.current?.cancel && source.current.cancel('GANTI TAB')
setIndex(ind)
}
/**
* List function to render component
*/
function listTab(){
const showTab = ['Message', 'Announce'].map((el, ind)=>
<TouchableOpacity key={ind.toString()} onPress={()=>handleChangeTab(ind)} style={{marginRight:8}}>
<View>
<Text>{el}</Text>
{ind == activeIndex && <View style={{height:2, width:20, backgroundColor:'red', alignSelf:'center'}} />}
</View>
</TouchableOpacity>
)
return(
<View style={{flexDirection:'row', marginBottom:14}}>
{showTab}
</View>
)
}
/**
* End list function to render component
*/
return(
<SafeAreaView style={{flex:1}}>
{listTab()}
{data == null
? <ActivityIndicator/>
: <Text>{data}</Text>
}
</SafeAreaView>
)
}
在useEffect
上,我有条件调用API依赖于activeIndex
,但是在handleChangeTab
中没有触发cancel,以防axios仍然获取旧的URL。
有人能指导我如何正确取消上述情况下的公理吗?
发布于 2021-05-07 14:53:24
在效果中使用本地令牌,并在清理回调中取消它:
React.useEffect(()=>{
setData(null)
const source = axios.CancelToken.source()
if(activeIndex == 0){
AxiosHTTP.get('http://httpstat.us/200?sleep=4000', {cancelToken: source.token})
.then(res=>{
setData(JSON.stringify(res.data))
})
} else {
AxiosHTTP.get('http://httpstat.us/200?sleep=4000', {cancelToken: source.token})
.then(res=>{
setData(JSON.stringify(res.data)+' Else')
})
}
return ()=> source.cancel() // <<<<<<<<<<<<<<
}, [activeIndex])
或者您可以使用自定义钩子支持开箱即用的可取消异步例程(自动可取消的获取演示):
import React from "react";
import { useAsyncEffect } from "use-async-effect2";
import cpAxios from "cp-axios";
/*
Notice: the related network request will also be aborted
Checkout your network console
*/
function TestComponent(props) {
const [cancel, done, result, err] = useAsyncEffect(
function* () {
return (yield cpAxios(props.url).timeout(props.timeout)).data;
},
{ states: true, deps: [props.url] }
);
return (
<div className="component">
<div className="caption">useAsyncEffect demo:</div>
<div>
{done ? (err ? err.toString() : JSON.stringify(result)) : "loading..."}
</div>
<button className="btn btn-warning" onClick={cancel} disabled={done}>
Cancel async effect
</button>
</div>
);
}
发布于 2021-05-07 17:18:42
您将axios源对象存储在source.current
中,因此令牌在source.current.token
中。
将代码从:{cancelToken: source.token}
更改为{cancelToken: source.current.token}
https://stackoverflow.com/questions/67416807
复制相似问题