[教程] ListView的使用和封装——实战React Native中级案例01
2017-05-29 05:51
639 查看
前言
在开发过程中最常见的任务就是建立一个列表,无论是联系人列表或是商品目录等等。为了提高开发效率,这里我们将对ListView进行整理和封装,使得其使用变得方便快捷。为了检验组件的可用性,我们将开发下图的示例。该程序包含一个列表,可在程序初始化后现实一个数组中的数据。在点击
Add Item按键后,列表将会添加新的项目。
这里要注意的是,ListView的部分应进行适当的封装,使得同样的组建可以快速的用于联系人列表或购物清单等场景。
想象驱动开发 (Wish-driven Development)
和测试驱动开发类似,想象驱动开发指的是先想象你的代码开发完成后应该如何使用,然后再进行开发,直到代码能够实现你描述的功能。我想只需要写X我的代码就能做到Y => 一直修改代码直至实现你的愿望
在这个例子中我们希望ListView可以这样使用:
// 代码仅用于展示概念,放到程序里运行不了不要找我 <MyListView data={this.state.data} row={<Row />} />
为了实现代码的高重用性,我们希望列表中的每一行的外观都由组建
<Row />决定,方便随时调整,然后作为一个
props传到组件中,同时我们还不希望对于数据进行管理,而仅仅传入一个数组,ListView就可以自动将数据分发给每个
<Row />组件。而数组发生变更的时候,
MyListView也应该自动更新。
处理dataSource和数据刷新
ListView的数据来自于dataSource,这个参数必须是一个
ListView.DataSource对象。所以我们采用了这样的方法定义dataSource:
首先,定义一个
MyListView类用来封装ListView:
class MyListView extends Component { // Initialize the hardcoded data constructor(props) { super(props); } render() { return ( <ListView /> ); } }
然后,将
state中的
dataSource设置为一个
ListView.DataSource类。
constructor(props) { super(props); this.state = { dataSource: new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}) }; }
在进行了上述设置后,我们就可以用
cloneWithRows方法更新dataSource了。这里
cloneWithRows的参数是一个数组,而返回值还是
ListView.DataSource类。这个方法将方便React比较新的
dataSource和原有的
dataSource,并且仅在数据发生变动的时候才对页面进新更新。
updateData(data) { this.setState({ dataSource: this.state.dataSource.cloneWithRows(data), }) }
最后,我们还需要使用
updateData()这个方法。
componentWillMount负责在组件第一次完成初始化,并且接收到props但是还没有
render前将state和props同步,而
componentWillReceiveProps则负责在每次props变更后进行同步。
componentWillMount() { this.updateData(this.props.data); } componentWillReceiveProps(nextProps) { if(this.props.data !== nextProps.data){ this.updateData(nextProps.data); } }
创建子元件并传递props值
下一步我们要做的是使每一行的外观变成一个元件,并且可以从外部传递进去。在文档中,ListView的基本用法是这样的。<ListView dataSource={this.state.dataSource} renderRow={(rowData) => <Text>{rowData}</Text>} />
即ListView会自动对于数据进行处理,并把每一行的数据作为
rowData传递给一个React Component。这里,我们对于文档中的例子进行一些小的修改就能够达到目的:
<ListView dataSource={this.state.dataSource} renderRow={(rowData) => { var newChild = React.cloneElement( this.props.row, {data:rowData} ); return newChild }}/>
这里,我们规定ListView应该有一个row参数,这个参数是一个组件,然后我们便用
React.cloneElement方法对这个组件进行复制,并将
rowData作为data参数传递给改组件。这样,这个组件就可通过下列方法使用
rowData数据了:
class Row extends Component { render() { return( <Text>{this.props.data}</Text> ) } }
代码展示
查看Demo:https://snack.expo.io/BkyPYRdZZimport React, {Component} from 'react';
import { StyleSheet, Text, View, ListView, Button } from 'react-native';
class MyListView extends Component {
// Initialize the hardcoded data
constructor(props) {
super(props);
this.state = {
dataSource: new
4000
ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2})
};
}
updateData(data) { this.setState({ dataSource: this.state.dataSource.cloneWithRows(data), }) }
componentWillMount() { this.updateData(this.props.data); } componentWillReceiveProps(nextProps) { if(this.props.data !== nextProps.data){ this.updateData(nextProps.data); } }
render() {
return (
<ListView
dataSource={this.state.dataSource}
renderRow={(rowData) => {
var newChild = React.cloneElement(this.props.row, {data:rowData});
return newChild
}}
/>
);
}
}
class Row extends Component { render() { return( <Text>{this.props.data}</Text> ) } }
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
data: ['row 1', 'row 2', 'row 3', 'row 4'],
row: 5
};
}
addItem(){
this.setState(function(prevState) {
return {
data: [...prevState.data, ('row ' + prevState.row)],
row: prevState.row + 1
};
});
}
render() {
return (
<View style={styles.container}>
<MyListView data={this.state.data} row={<Row />} />
<Button title="Add Item" onPress={() => this.addItem()} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
paddingTop: 22,
},
});
版权声明:本作品采用知识共享署名 3.0 未本地化版本许可协议进行许可,欢迎转载,请注明转载自Andrew Xie的学习笔记(http://blog.csdn.net/andrewxy)。
相关文章推荐
- ReactNative基础(四)了解ListView的使用、实现GridView效果、编写一个真实网络请求案例
- react-native android教程一(AS中使用react-native)
- [转]Ultra Fractal教程系列43——动画功能的使用01——创建动画分形案例
- React Native教程之Navigator的使用
- [教程] React Native基础实战(1)—— 制作一个简单的按钮
- React-Native学习笔记 使用ListView加载网络数据
- React Native Android原生模块开发实战|教程|心得|如何创建React Native Android原生模块
- React-native 常见问题:Warning 当使用组件 react-native-gifted-listview
- react-native 在android封装原生listView
- React native Listview 使用react-redux时候更新不起效果
- react native Modal使用以及封装
- React Native 学习笔记二十(关于ListView的使用)
- React-Native傻瓜式学习笔记(一):ListView的简单使用
- react-native listview使用
- 使用react-native做一个简单的应用-01项目介绍
- 【React Native实战教程】GitHub Trending API数据的获取
- React Native实战项目企业通信录(含视频教程)-环境搭建
- React Native实战项目企业通信录(含视频教程)- 登录功能实现
- React Native 网络请求封装:使用Promise封装fetch请求
- React Native 网络请求封装:使用Promise封装fetch请求