reactnative ajax 同步,React Native从网络拉取数据并填充列表

本文工作,涉及到以下几个知识点

请求网络并得到数据

创建Button并触发按钮事件测试网络

创建列表listview

创建CELL

根据返回的数据填充CELL

使用Fetch请求网络

React Native提供了和web标准一致的Fetch API,用于满足开发者访问网络的需求。如果你之前使用过XMLHttpRequest(即俗称的ajax)或是其他的网络API,那么Fetch用起来将会相当容易上手。这篇文档只会列出Fetch的基本用法,并不会讲述太多细节,你可以使用你喜欢的搜索引擎去搜索fetch api关键字以了解更多信息。

发起网络请求

要从任意地址获取内容的话,只需简单地将网址作为参数传递给fetch方法即可(fetch这个词本身也就是获取的意思):

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

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

提供两个可用的url,返回json

http://facebook.github.io/react-native/movies.json

http://bbs.reactnative.cn/api/category/3

可以替换下面的url

fetch('https://mywebsite.com/endpoint/', {

method: 'POST',

headers: {

'Accept': 'application/json',

'Content-Type': 'application/json',

},

body: JSON.stringify({

firstParam: 'yourValue',

secondParam: 'yourOtherValue',

})

})

TIPS:本人用的是xcode8做测试,遇到网络请求不通的情况,解决方法是在info.plist加入一项允许http的请求,这是由于兼容ios9+的一种方式,通过看控制台的log知道访问的结果.

查看测试结果也可以利用工具Charles

NSAllowsArbitraryLoads

创建按钮并触发事件 TouchableHighlight

由于RN的特点,没有直接对Button封装出来,但是有可用的可点击组件,会相应点击事件。

中文网TouchableHightlight介绍

本组件用于封装视图,使其可以正确响应触摸操作。当按下的时候,封装的视图的不透明度会降低,同时会有一个底层的颜色透过而被用户看到,使得视图变暗或变亮。在底层实现上,实际会创建一个新的视图到视图层级中,如果使用的方法不正确,有时候会导致一些不希望出现的视觉效果。譬如没有给视图的backgroundColor显式声明一个不透明的颜色。

例子:

renderButton: function() {

return (

style={styles.button}

source={require('./button.png')}

/>

);

},

注意:TouchableHighlight只支持一个子节点

如果你希望包含多个子组件,用一个View来包装它们。

所以结合上面的网络请求,我们的按钮触发事件可以这样写

buttonTap=()=>{

fetch( 'http://bbs.reactnative.cn/api/category/3')

.then((response)=>response.json())

.then((jsondata) =>{

console.log(jsondata);

const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});

this.setState({dataSource: ds.cloneWithRows(jsondata.topics)});

this.setState({title:jsondata.description});

//alert(jsondata);

})

.catch((error)=>{

alert(error);

console.warning(error);

});

};

按钮的布局代码

render() {

return (

style={styles.button}

source={require('./img/favicon.png')}

/>

);

}

创建ListView

ListView组件用于显示一个垂直的滚动列表,其中的元素之间结构近似而仅数据不同。

ListView更适于长列表数据,且元素个数可以增删。和ScrollView不同的是,ListView并不立即渲染所有元素,而是优先渲染屏幕上可见的元素。

ListView组件必须的两个属性是dataSource和renderRow。dataSource是列表的数据源,而renderRow则逐个解析数据源中的数据,然后返回一个设定好格式的组件来渲染。

下面的例子创建了一个简单的ListView,并预设了一些模拟数据。首先是初始化ListView所需的dataSource,其中的每一项(行)数据之后都在renderRow中被渲染成了Text组件,最后构成整个ListView。

rowHasChanged函数也是ListView的必需属性。这里我们只是简单的比较两行数据是否是同一个数据(===符号只比较基本类型数据的值,和引用类型的地址)来判断某行数据是否变化了。

import React, { Component } from 'react';

import { AppRegistry, ListView, Text, View } from 'react-native';

class ListViewBasics extends Component {

// 初始化模拟数据

constructor(props) {

super(props);

const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});

this.state = {

dataSource: ds.cloneWithRows([

'John', 'Joel', 'James', 'Jimmy', 'Jackson', 'Jillian', 'Julie', 'Devin'

])

};

}

render() {

return (

dataSource={this.state.dataSource}

renderRow={(rowData) => {rowData}}

/>

);

}

}

// 注册应用(registerComponent)后才能正确渲染

// 注意:只把应用作为一个整体注册一次,而不是每个组件/模块都注册

AppRegistry.registerComponent('ListViewBasics', () => ListViewBasics);

以上介绍了一个简单的ListView ,然而现实中的CELL并没有如此简单,我们需要重构CELL的组织方式

创建展示的CELL

如果学过RN的布局方式,定制化CELL就是个简单的事情,此处需要用到alighitmes,justifycontent,具体的可以参考 React Native 的布局方式flextbox

直接给出代码

class CELL extends Component{

constructor(props){

super(props);

this.state = { detailTitle:'aaaa'};

}

render(){

return(

{this.props.title}

{this.props.detailTitle}

);

}

}

要实现以上的需求,效果图如下

1c5dc5cd6d97

Paste_Image.png

大伙可以先不看代码,自己组织代码试一下!

有问题欢迎在下面留言

不要吝啬自己的喜欢,有用的话点个赞吧

源代码如下:

import React, { Component } from 'react';

import {

AppRegistry,

StyleSheet,

Text,

TextInput,

Image,

View,ScrollView,

ListView,

TouchableHighlight,

} from 'react-native';

class RNCSDemo extends Component {

// 初始化模拟数据

constructor(props) {

super(props);

const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});

this.state = {

dataSource: ds.cloneWithRows([

// 'John', 'Joel', 'James', 'Jimmy', 'Jackson', 'Jillian', 'Julie', 'Devin'

])

};

this.buttonTap();//初始化

}

getMoviesFromApiAsync() {

return fetch('http://facebook.github.io/react-native/movies.json',

{

headers:{

'Accept': 'application/json',

'Content-Type':'application/json',

}

})

.then((response) => response.json())

.then((responseJson) => {

return responseJson.movies;

})

.catch((error) => {

console.error(error);

});

}

buttonTap=()=>{

fetch( 'http://bbs.reactnative.cn/api/category/3'

// , {

// method: 'GET',

// headers: {

// 'Accept': 'application/json',

// 'Content-Type': 'application/json',

// },

// body: JSON.stringify({

// } )

// }

).then((response)=>response.json())

.then((jsondata) =>{

console.log(jsondata);

const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});

this.setState({dataSource: ds.cloneWithRows(jsondata.topics)});

this.setState({title:jsondata.description});

//alert(jsondata);

})

.catch((error)=>{

alert(error);

console.warning(error);

});

};

render() {

return (

style={styles.button}

source={require('./img/favicon.png')}

/>

{this.state.title}

dataSource={this.state.dataSource}

renderRow={(rowData) => }

/>

);

}

}

class CELL extends Component{

constructor(props){

super(props);

this.state = { detailTitle:'aaaa'};

}

render(){

return(

{this.props.title}

{this.props.detailTitle}

);

}

}

const styles= StyleSheet.create({

container:{flex:1,

justifyContent:'center',

backgroundColor: '#F5FC00',}

});

AppRegistry.registerComponent('RNCSDemo', () => RNCSDemo);

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值