在 react-native 中取消 fetch 请求

AHm*_*Net 9 android fetch react-native

有什么办法可以中止 react-native app 上的 fetch 请求吗?

class MyComponent extends React.Component {
  state = { data: null };

  componentDidMount = () =>
    fetch('http://www.example.com')
      .then(data => this.setState({ data }))
      .catch(error => {
        throw error; 
      });

  cancelRequest = () => {
   //???
  };

  render = () => <div>{this.state.data ? this.state.data : 'loading'}</div>;
}
Run Code Online (Sandbox Code Playgroud)

我尝试了课堂上的abort功能,AbortController但它不起作用!!

...
abortController = new window.AbortController();

cancelRequest =  () => this.abortController.abort();

componentDidMount = () =>
        fetch('http://www.example.com', { signal: this.abortController.signal })
          ....
Run Code Online (Sandbox Code Playgroud)

请任何帮助!

小智 10

你不再需要任何 polyfill 来中止 React Native 0.60更改日志中的请求

这是react-native文档中的一个快速示例:

/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @format
 * @flow
*/

'use strict';

const React = require('react');
const {Alert, Button, View} = require('react-native');

class XHRExampleAbortController extends React.Component<{}, {}> {
  _timeout: any;

  _submit(abortDelay) {
    clearTimeout(this._timeout);
    // eslint-disable-next-line no-undef
    const abortController = new AbortController();
    fetch('https://facebook.github.io/react-native/', {
      signal: abortController.signal,
    })
      .then(res => res.text())
      .then(res => Alert.alert(res))
      .catch(err => Alert.alert(err.message));
    this._timeout = setTimeout(() => {
          abortController.abort();
    }, abortDelay);
  }

  componentWillUnmount() {
    clearTimeout(this._timeout);
  }

  render() {
    return (
      <View>
        <Button
          title="Abort before response"
          onPress={() => {
            this._submit(0);
          }}
        />
        <Button
          title="Abort after response"
          onPress={() => {
            this._submit(5000);
          }}
        />
      </View>
    );
  }
}

module.exports = XHRExampleAbortController;
Run Code Online (Sandbox Code Playgroud)


Gia*_*one 5

我已经写了很多关于这个主题的文章。你也可以在这里找到我在这里打开的关于 React Native 中OLD缺少 AbortController的第一个问题

RN 0.60.0 提供了支持,您可以在我的博客上找到一篇关于此的文章一篇文章,该文章将为您提供一个简单的代码,让您开始在 React Native 中发出可中止的请求(以及更多)。它还为不支持的环境实现了一些 polyfill(例如 RN < 0.60)。

  • 实际上,最好将代码放在这里,并另外添加指向您的文章的链接,以便更深入地理解。 (2认同)

AHm*_*Net 1

最好的解决方案是使用 rxjs observables + axios/fetch 而不是 Promise,中止请求 => 取消订阅 observable :

import Axios from "axios";
import {
    Observable
} from "rxjs";

export default class HomeScreen extends React.Component {
    subs = null;

    doStuff = () => {
        let observable$ = Observable.create(observer => {
            Axios.get('https://jsonplaceholder.typicode.com/todos', {}, {})
                .then(response => {
                    observer.next(response.data);
                    observer.complete();
                })
        });

        this.subs = observable$.subscribe({
            next: data => console.log('[data] => ', data),
            complete: data => console.log('[complete]'),
        });

    }

    cancel = () =>
        if (this.subs) this.subs.unsubscribe()

    componentWillUnmount() {
        if (this.subs) this.subs.unsubscribe();
    }

}
Run Code Online (Sandbox Code Playgroud)

这就对了 :)

  • 这不会取消底层的 axios 请求。只是对结果的订阅。 (10认同)