首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用条件调用API管理useEffect中的取消Axios

用条件调用API管理useEffect中的取消Axios
EN

Stack Overflow用户
提问于 2021-05-06 11:01:29
回答 2查看 600关注 0票数 1

我有两个按钮显示不同的内容(消息和公告)

假设在初始挂载时调用API获取Message列表,在用户从API获得响应之前,使用press Announcement按钮获取Announcement列表。

这里我想取消Message的API调用,并调用Announcement API,

我试过这段代码,但没有结果:

代码语言:javascript
运行
复制
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。

有人能指导我如何正确取消上述情况下的公理吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-05-07 14:53:24

在效果中使用本地令牌,并在清理回调中取消它:

代码语言:javascript
运行
复制
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])

或者您可以使用自定义钩子支持开箱即用的可取消异步例程(自动可取消的获取演示):

代码语言:javascript
运行
复制
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>
  );
}
票数 1
EN

Stack Overflow用户

发布于 2021-05-07 17:18:42

您将axios源对象存储在source.current中,因此令牌在source.current.token中。

将代码从:{cancelToken: source.token}更改为{cancelToken: source.current.token}

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67416807

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档