我正在尝试使用本机反应实现搜索和过滤栏,但不太确定如何使用 DataSource 对象。数据采用 JSON 格式,应执行以下操作:
- 基于查询字符串对提供的 JSON进行全文搜索
- 基于标记的过滤,使用作为标记提供的标记
这是关于RNPlay (Link)的一个非常简单的示例。
如何在 React Native 中实现搜索和过滤功能?
import React, {Component} from 'react';
import { AppRegistry, View, ListView, Text, TextInput, StyleSheet, TouchableOpacity } from 'react-native';
const FILTERS = [
{
tag: "clever", active: false
}, {
tag: "scary", active: false
}, {
tag: "friendly", active: false
}, {
tag: "obedient", active: false
}
];
const FIELDS = [
{
title:"Dog",
subtitle: "Bulldog",
tags: [ { tag: "clever" }, { tag: "scary" } ]
}, {
title:"Cat",
subtitle:"Persian cat",
tags: [ { tag: "friendly" }, { tag: "obedient" } ]
}, {
title:"Dog",
subtitle:"Poodle",
tags: [ { tag: "obedient" } ]
}
];
class SampleApp extends Component {
constructor(props) {
super(props);
var ds = new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2,
});
var ds2 = new ListView.DataSource({
rowHasChanged: (row1, row2) => row1.active !== row2.active,
});
this.state = {
dataSource: ds.cloneWithRows(FIELDS),
dataSource2: ds2.cloneWithRows(FILTERS),
filters: FILTERS,
};
}
renderFilter(filter) {
return (
<TouchableOpacity onPress={this.handleClick.bind(this, filter)}>
<Text style={{fontSize: 24, backgroundColor:(filter.active)?'red':'grey', margin:5}}>{filter.tag}</Text>
</TouchableOpacity>
);
}
renderField(field) {
return (
<View style={{flexDirection:'column', borderWidth: 3, borderColor: 'yellow'}}>
<Text style={{fontSize: 24}}>{field.title}</Text>
<Text style={{fontSize: 24}}>{field.subtitle}</Text>
{field.tags.map((tagField) => {
return (
<View style={{backgroundColor:'blue'}}>
<Text style={{fontSize: 24}}>{tagField.tag}</Text>
</View>
);
})}
</View>
);
}
handleClick(filter) {
const newFilters = this.state.filters.map(a => {
let copyA = {...a};
if (copyA.tag === filter.tag) {
copyA.active = !filter.active;
}
return copyA;
});
this.setState({
dataSource2: this.state.dataSource2.cloneWithRows(newFilters),
filters: newFilters
});
}
setSearchText(event) {
let searchText = event.nativeEvent.text;
this.setState({searchText});
}
render() {
return (
<View>
<TextInput
style={styles.searchBar}
value={this.state.searchText}
onChange={this.setSearchText.bind(this)}
placeholder="Search" />
<ListView
style={{flexDirection:'row', flex:1, flexWrap:'wrap'}}
horizontal={true}
dataSource={this.state.dataSource2}
renderRow={this.renderFilter.bind(this)}
/>
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderField.bind(this)}
/>
</View>
);
}
}
const styles = StyleSheet.create({
searchBar: {
marginTop: 30,
fontSize: 40,
height: 50,
flex: .1,
borderWidth: 3,
borderColor: 'red',
},
});
AppRegistry.registerComponent('SampleApp', () => SampleApp);