RN入门基础10:网络 fetch

一、介绍

很多移动应用都需要从远程地址中获取数据或资源。可能需要给某个REST API发起POST请求以提交用户数据,又或者可能仅仅需要从某个服务器上获取一些静态内容,这就需要网络了。

1.使用Fetch

React Native提供了和web标准一致的Fetch API,用于满足开发者访问网络的需求。

如果之前使用过XMLHttpRequest(即俗称的ajax)或是其他的网络API,那么Fetch用起来将会相当容易上手。

这篇文档只列出Fetch的基本用法,不讲述太多细节。

1.1发起网络请求

要从任意地址获取内容的话,只需简单地将网址作为参数传递给fetch方法即可:

fetch('https://mywebsite.com/mydata.json')

Fetch还有可选的第二个参数,可以用来定制HTTP请求一些参数。可以指定header参数,或是指定使用POST方法,又或是提交数据等等:

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'
})

1.2处理服务器的响应数据

扫描二维码关注公众号,回复: 2660227 查看本文章

网络请求天然是一种异步操作。Fetch 方法会返回一个Promise,这种模式可以简化异步风格的代码:

getMoviesFromApiAsync() {
  return fetch('http://facebook.github.io/react-native/movies.json')
    .then((response) => response.json())
    .then((responseJson) => {
      return responseJson.movies;
    })
    .catch((error) => {
      console.error(error);
    });
}

可以在React Native应用中使用ES7标准中的async/await 语法:

// 注意这个方法前面有async关键字
async getMoviesFromApi() {
  try {
    // 注意这里的await语句,其所在的函数必须有async关键字声明
    let response = await fetch('http://facebook.github.io/react-native/movies.json');
    let responseJson = await response.json();
    return responseJson.movies;
  } catch(error) {
    console.error(error);
  }
}

别忘了catch住fetch可能抛出的异常,否则出错时你可能看不到任何提示。

默认情况下,iOS会阻止所有非HTTPS的请求。如果你请求的接口是http协议,那么首先需要添加一个App Transport Securty的例外,详细可参考这篇帖子

二、举例

//从网络获取数据,并展示到UI上
//用var变量声明一个网络请求的网址
var REQUEST_URL = 'http://facebook.github.io/react-native/movies.json';
//定义一个样式
const styles = StyleSheet.create({
    container:{
        flex:1,flexDirection:'row',justifyContent:'center',alignItems:'center',backgroundColor:'#F5FCFF'
    },
    thumbnail:{
        width:100,height:80
    },
    rightContainer:{
        flex:1
    },
    title:{
        fontSize:20,marginBottom:8,textAlign:'center'
    },
    year:{
        textAlign:'center'
    },
});

export default class myprojectname extends Component
{
    constructor(props) {
        super(props);

        // state是用来监控从网络加载的数据movies状态改变,
        // 数据返回后会触发setState方法修改movies的内容,
        // 这时对应UI监控state的地方会自动刷新
        this.state = {
            movies: null,
        };
    }

    //render方法用于返回组件创建的UI对象
    render()
    {
        // 根据state的movies来判断,
        // 如果movies没有东西,则调用renderLoadingView方法返回loading界面。
        // 如果movies中有内容,则取出其中一个dic,传入renderMovie方法,返回指定显示内容的UI界面
        if (!this.state.movies) {
            return this.renderLoadingView();
        }
        var movie = this.state.movies[0];
        return this.renderMovie(movie);
    }

    //fetchData方法为RN的网络请求方法
    // fetch传入URL和GET请求,
    // .then中将response返回转为json,赋值给responseData,
    // 调用setState方法,给movies赋值,并捕获异常进行回调。
    /*fetchData()
    {
        return fetch(REQUEST_URL, {method: 'GET'})
            .then((response) => response.json())
            .then((responseData) => {
                this.setState({
                    movies:responseData.movies,
                });
            })
            .catch((error) => {
                callback(error);
            });
    }*/
    //ES7 await
    async fetchData() {
        try {
            // 注意这里的await语句,其所在的函数必须有async关键字声明
            let response = await fetch(REQUEST_URL);
            let responseJson = await response.json();
            this.setState({
                movies:responseJson.movies,
            });
            return responseJson.movies;
        } catch(error) {
            console.error(error);
        }
    }

    //组件加载完毕后调用请求网络的方法。
    componentDidMount()
    {
        this.fetchData();
    }

    // 返回加载中的界面
    renderLoadingView()
    {
        return (
            <View style={styles.container}>
                <Text>
                    正在加载电影数据......
                </Text>
            </View>
        );
    }

    // 将网络请求返回的movie传进来,初始化对应的View,Image,Text显示图片,文本信息。
    renderMovie(movie)
    {
        return (
            <View style={styles.container}>
                <Image source={{uri:movie.movies}}
                       style={styles.thumbnail} />
                <View style={styles.rightContainer}>
                    <Text style={styles.title}>{movie.title}</Text>
                    <Text style={styles.year}>{movie.releaseYear}</Text>
                </View>
            </View>
        );
    }
}

 

猜你喜欢

转载自blog.csdn.net/jinmie0193/article/details/81483935