Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

React Native入门(八)之网络请求Fetch

$
0
0

前言

最近有些事情要忙,RN相关的内容没有更新,现在就来了解一下RN中进行网络请求相关的内容!

介绍

React Native提供了和web标准一致的Fetch API,用于满足开发者访问网络的需求。
关于Fetch API的相关内容,可以到下边网站了解:
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
我们这先大致说一下在RN中使用Fetch API 进行网络请求的例子,然后再去了解Fecth的相关内容!

使用Fetch

Fetch API 提供一个fetch()方法,要从任意地址获取内容的话,只需简单地将网址作为参数传递给fetch方法即可。

fetch('https://facebook.github.io/react-native/movies.json')

Fetch API 是基于 Promise 设计,那么关于 Promise的内容可以参考下面的教程:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
这里简单提一下:
我们知道网络请求是一个天然的异步操作,Fetch 方法会返回一个Promise,这种模式可以简化异步风格的代码。Promise 对象是一个返回值的代理,它允许你为异步操作的成功或失败指定处理方法。 这使得异步方法可以像同步方法那样返回值:异步方法会返回一个包含了原返回值的promise 对象来替代原返回值。

Promise有两个重要的方法,分别是resolve方法和reject方法。如果异步操作成功,则用resolve方法将Promise对象的状态变为“成功”(即从pending变为resolved);如果异步操作失败,则用reject方法将状态变为“失败”(即从pending变为rejected)。

好了,知道了这些之后,我们来说一下如果处理网络请求返回的结果!

Fetch 方法会返回一个Promise,一个 Promiseresolve时会回传 Response 对象,也就是说请求成功,会回传一个Response 对象,这个Response 对象就包含了所有返回结果的信息!

好,下面看一个例子,也是RN中文网的例子,这里做了一些改动!
首先,我们在浏览器看一下网络请求到的内容:

{
  "title": "The Basics - Networking",
  "description": "Your app fetched this from a remote endpoint!",
  "movies": [
    { "title": "Star Wars", "releaseYear": "1977"},
    { "title": "Back to the Future", "releaseYear": "1985"},
    { "title": "The Matrix", "releaseYear": "1999"},
    { "title": "Inception", "releaseYear": "2010"},
    { "title": "Interstellar", "releaseYear": "2014"}
  ]
}

这个一个请求到一些电影信息的json数据。
这里我们使用fetch发送网络请求,然后将得到的json数据使用列表展示出来,下面看一下代码:

class NetText extends Component {
  constructor(props) { //构造器
    super(props);
    this.state = {  //定义的三个状态
      title: '',
      description: '',
      movies: ''
    };
  }

  //列表点击事件
  itemClick(item, index) {
    alert('点击了第' + index + '项,电影名称:' + item.title + '上映年份:' + item.releaseYear);
  }

  //FlatList的key
  _keyExtractor = (item, index) => index;

  //子item渲染
  _renderItem = ({item, index}) => {
    return (
      <TouchableOpacity
        activeOpacity={0.5}
        onPress={this.itemClick.bind(this, item, index)}>
        //这里index为奇偶数给不同的背景
        <View style={[WebTestStyles.item, {backgroundColor: index % 2 == 0 ? 'lightgray' : 'whitesmoke'}]}>
          <Text style={WebTestStyles.itemTitle}>{item.title}</Text>
          <Text style={WebTestStyles.itemYear}>上映年份:{item.releaseYear}</Text>
        </View>

      </TouchableOpacity>
    );
  }

  //列表分割线
  _itemDivide = () => {
    return (
      <View style={{height: 1, backgroundColor: 'dimgray'}}/>
    );
  }

  //getMoviesFromApiAsync() {
  _fetchData = () => {
    fetch('https://facebook.github.io/react-native/movies.json')
      .then((response) => response.json())//把response转为json格式
      .then((jsondata) => {    //上面的转好的json
        //alert(jsondata.movies[0].title);
        this.setState({ //将获取到的数据更新到state中
          title: jsondata.title,
          description: jsondata.description,
          movies: jsondata.movies,
        })
      })
      .catch((error) => {
        console.error(error);
      });
  };

  render() {
    return (
      <View style={WebTestStyles.container}>
        <Text style={WebTestStyles.title}>{this.state.title}</Text>
        <Text style={WebTestStyles.description}>{this.state.description}</Text>
        <FlatList   //列表组件
          style={{marginTop: 20}}
          data={this.state.movies}
          keyExtractor={this._keyExtractor}
          renderItem={this._renderItem}
          ItemSeparatorComponent={this._itemDivide}/>
        <Button title="请求网络" onPress={this._fetchData}/>
      </View>
    );
  }
}
;

const WebTestStyles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'column'
  },

  title: {
    fontSize: 20,
    fontWeight: 'bold',
    alignSelf: 'center'

  },

  description: {
    fontSize: 12,
    alignSelf: 'center'
  },

  item: {
    padding: 10
  },
  itemTitle: {
    fontSize: 18,
    fontWeight: 'bold'
  },
  itemYear: {
    fontSize: 16,
  }
})

然后看一下效果:
这里写图片描述

代码的话,基本上没有什么好说的,就是点击一个按钮去请求网络,然后拿到json格式的数据,两个文本字段,一个数组,然后把数组设置为FlatList的data,将电影以列表形式展示!

Fetch相关API

请求参数的设置

上面我们在请求网络的时候,只是用fetch(url)这样的形式,我们也可以设置其他的参数来请求网络,如下所示:

  • method: 请求使用的方法,如 GETPOST
  • headers: 请求的头信息,形式为 Headers 对象或 ByteString。
  • body: 请求的 body 信息:可能是一个 Blob、BufferSource、FormData、URLSearchParams 或者 USVString 对象。注意 GET 或 HEAD 方法的请求不能包含 body 信息
  • mode: 请求的模式,如 corsno-cors 或者 same-origin
  • credentials: 请求的 credentials,如 omitsame-origin 或者 include
  • cache: 请求的 cache 模式: default, no-store, reload, no-cache, force-cache, 或者 only-if-cached

类似这样:

fetch('https://mywebsite.com/endpoint/', {
  method: 'POST',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    firstParam: 'yourValue',
    secondParam: 'yourOtherValue',
  })
})

如果你的服务器无法识别上面POST的数据格式,那么可以尝试传统的form格式,示例如下:

fetch('https://mywebsite.com/endpoint/', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
  },
  body: 'key1=value1&key2=value2'
})

这个得话,就需要和做后台的同事提前沟通好就行了!

自定义Header

关于请求头Header的话,还可以通过 Headers() 构造函数来创建一个你自己的 headers 对象。

var myHeaders = new Headers();
myHeaders.append("Content-Type", "text/plain");
myHeaders.append("Content-Length", content.length.toString());
myHeaders.append("X-Custom-Header", "ProcessThisImmediately");

也可以传一个多维数组或者对象字面量:

myHeaders = new Headers({
  "Content-Type": "text/plain",
  "Content-Length": content.length.toString(),
  "X-Custom-Header": "ProcessThisImmediately",
});

自定义Request

除了上面的用法,我们还可以通过使用Request()构造函数来创建一个request对象,然后再作为参数传给fetch()。这里就相当于把url和header或者其他的参数综合起来!
比如:

var url='https://mywebsite.com/endpoint/';
var myOptions = { method: 'GET',
               headers: myHeaders,
               mode: 'cors',
               cache: 'default' };
var myRequest = new Request(url, myOptions );

fetch(myRequest)
  .then()
  ...

Response

属性:

  • status (number) - HTTP请求结果参数,在100–599 范围
  • statusText (String) - 服务器返回的状态报告
  • ok (boolean) - 如果返回200表示请求成功则为true
  • headers (Headers) - 返回头部信息,下面详细介绍
  • url (String) - 请求的地址

方法:

  • text() - 以string的形式生成请求text
  • json() - 生成JSON.parse(responseText)的结果
  • blob() - 生成一个Blob
  • arrayBuffer() - 生成一个ArrayBuffer
  • formData() - 生成格式化的数据,可用于其他的请求

其他方法:

  • clone()
  • Response.error()
  • Response.redirect()

上边就是Fetch常用的API,其他的API可以参考Fetch_API,也就是上边的网站!

参考文章
【译】fetch用法说明
传统 Ajax 已死,Fetch 永生

作者:aiynmimi 发表于2017/8/18 11:56:47 原文链接
阅读:12 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>