T. *_*ans 9 javascript reactjs react-native
我正在尝试根据搜索栏文本搜索平面列表.我遇到的问题是,当用户输入错误时...说他们想输入"汉堡"但是错误地键入"burget"然后它不会返回任何内容.当用户删除"t"时,它应该再次重新呈现平面列表,最后一个文本与"burge"部分匹配.
注意:使用react-native-elements搜索栏,它允许我用e或event调用文本.
到目前为止我在Main.js文件中有什么:
searchText = (e) => {
let text = e.toLowerCase();
let trucks = this.state.data;
// search by food truck name
let filteredName = trucks.filter((truck) => {
return truck.name.toLowerCase().match(text);
});
// if no match and text is empty
if(!text || text === '') {
console.log('change state');
this.setState({
data: initial
});
}
// if no name matches to text output
else if(!Array.isArray(filteredName) && !filteredName.length) {
console.log("not name");
this.setState({
data: [],
});
}
// if name matches then display
else if(Array.isArray(filteredName)) {
console.log('Name');
this.setState({
data: filteredName,
});
}
};
<View style={styles.container}>
<SearchBar
round
lightTheme
containerStyle={styles.search}
ref="search"
textInputRef="searchText"
onChangeText={this.searchText.bind(this)}
placeholder='Search by Truck Name...'
/>
<TruckList getTruck={(truck) => this.setTruck(truck)} truckScreen={this.truckScreen} data={this.state.data}/>
</View>
Run Code Online (Sandbox Code Playgroud)
然后是TruckList.JS:
export default class TruckList extends Component {
// rendering truck screen
renderTruckScreen = (item) => {
this.props.truckScreen();
this.props.getTruck(item);
}
render() {
return(
<List style={styles.list}>
<FlatList
data={this.props.data}
renderItem={({ item }) => (
<ListItem
roundAvatar
avatar={{uri: item.pic1}}
avatarStyle={styles.avatar}
title={item.name}
titleStyle={styles.title}
subtitle={
<View style={styles.subtitleView}>
<Text style={styles.subtitleFood}>{item.food}</Text>
<View style={styles.subtitleInfo}>
<Icon
name="favorite"
size={20}
color={"#f44336"}
style={styles.subtitleFavorite}
/>
<Text style={styles.subtitleFavoriteText}>{item.favorited} favorited</Text>
</View>
</View>
}
onPress={() => this.renderTruckScreen(item)}
/>
)}
keyExtractor={(item) => item.uid}
ListFooterComponent={this.footer}
/>
</List>
)
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试过其他一些方法无济于事.我见过的唯一可用于React Native的解决方案是ListView,它会及时折旧.所以我试图用新的FlatList组件来做这件事.
谢谢你的帮助!
小智 16
当我尝试在新的FlatList组件上实现过滤器/搜索功能时,我今天遇到了同样的问题.这就是我设法解决它的方法:
通过在名为noData的父组件状态中创建另一个项目,可以在没有与搜索匹配的结果时将其设置为true,然后有条件地呈现FlatList.
我的实现与您的实现略有不同,但如果我必须调整您的代码,它将看起来像这样:
Searchtext功能:
searchText = (e) => {
let text = e.toLowerCase()
let trucks = this.state.data
let filteredName = trucks.filter((item) => {
return item.name.toLowerCase().match(text)
})
if (!text || text === '') {
this.setState({
data: initial
})
} else if (!Array.isArray(filteredName) && !filteredName.length) {
// set no data flag to true so as to render flatlist conditionally
this.setState({
noData: true
})
} else if (Array.isArray(filteredName)) {
this.setState({
noData: false,
data: filteredName
})
}
}
Run Code Online (Sandbox Code Playgroud)
然后将noData bool传递给您的TruckList组件:
<TruckList getTruck={(truck) => this.setTruck(truck)}
truckScreen={this.truckScreen} data={this.state.data} noData={this.state.noData}/>
Run Code Online (Sandbox Code Playgroud)
只有在有结果的情况下才会在TruckList组件中渲染FlatList:
<List style={styles.list}>
{this.props.noData ? <Text>NoData</Text> : <FlatList {...} />}
</List>
Run Code Online (Sandbox Code Playgroud)
然后应该处理用户输入错误 - 因为它会在没有结果时立即重新呈现平面列表,并在您删除键入错误时记住先前的搜索状态.
如果有帮助,请告诉我!
Met*_*nol 13
对于有用的内存搜索,您应该单独保留初始数据。
我有更简单的解决方案。
此解决方案用于对 FlatList 的数据进行内存搜索,并使用它的 String.prototype?.includes() 方法来搜索子字符串。
您可以在此要点中找到该组件的完整源代码; https://gist.github.com/metehansenol/46d065b132dd8916159910d5e9586058
我的初始状态;
this.state = {
searchText: "",
data: [],
filteredData: []
};
Run Code Online (Sandbox Code Playgroud)
我的 SearchBar 组件(它来自 react-native-elements 包);
<SearchBar
round={true}
lightTheme={true}
placeholder="Search..."
autoCapitalize='none'
autoCorrect={false}
onChangeText={this.search}
value={this.state.searchText}
/>
Run Code Online (Sandbox Code Playgroud)
我的搜索方法;
search = (searchText) => {
this.setState({searchText: searchText});
let filteredData = this.state.data.filter(function (item) {
return item.description.includes(searchText);
});
this.setState({filteredData: filteredData});
};
Run Code Online (Sandbox Code Playgroud)
最后是我的 FlatList 的 DataSource 表达式;
<FlatList
data={this.state.filteredData && this.state.filteredData.length > 0 ? this.state.filteredData : this.state.data}
keyExtractor={(item) => `item-${item.id}`}
renderItem={({item}) => <ListItem
id={item.id}
code={item.code}
description={item.description}
/>}
/>
Run Code Online (Sandbox Code Playgroud)
快乐编码...
更新: 此博客可以帮助您更好地理解FlatList中的搜索.
仅供参考: 如果您拥有庞大的在线数据,那么您也可以使用algolia.
我为我调整了上面的代码,以使其正常工作.其原因是,当用户删除最后一个错误的字符,代码搜索从以前的搜索列表(状态)不包含所有对象,但它必须从可用的完整列表,搜索这个新的字符串.所以,我现在有两个清单.一个包含完整的对象列表,第二个包含仅在搜索时更改的对象的渲染列表.
handleSearchInput(e){
let text = e.toLowerCase()
let fullList = this.state.fullListData;
let filteredList = fullList.filter((item) => { // search from a full list, and not from a previous search results list
if(item.guest.fullname.toLowerCase().match(text))
return item;
})
if (!text || text === '') {
this.setState({
renderedListData: fullList,
noData:false,
})
} else if (!filteredList.length) {
// set no data flag to true so as to render flatlist conditionally
this.setState({
noData: true
})
}
else if (Array.isArray(filteredList)) {
this.setState({
noData: false,
renderedListData: filteredList
})
}
}
Run Code Online (Sandbox Code Playgroud)
//This is an example code to Add Search Bar Filter on Listview//
import React, { Component } from 'react';
//import react in our code.
import {
Text,
StyleSheet,
View,
FlatList,
TextInput,
ActivityIndicator,
Alert,
} from 'react-native';
//import all the components we are going to use.
export default class App extends Component {
constructor(props) {
super(props);
//setting default state
this.state = { isLoading: true, text: '' };
this.arrayholder = [];
}
componentDidMount() {
return fetch('https://jsonplaceholder.typicode.com/posts')
.then(response => response.json())
.then(responseJson => {
this.setState(
{
isLoading: false,
dataSource: responseJson
},
function() {
this.arrayholder = responseJson;
}
);
})
.catch(error => {
console.error(error);
});
}
SearchFilterFunction(text) {
//passing the inserted text in textinput
const newData = this.arrayholder.filter(function(item) {
//applying filter for the inserted text in search bar
const itemData = item.title ? item.title.toUpperCase() : ''.toUpperCase();
const textData = text.toUpperCase();
return itemData.indexOf(textData) > -1;
});
this.setState({
//setting the filtered newData on datasource
//After setting the data it will automatically re-render the view
dataSource: newData,
text: text,
});
}
ListViewItemSeparator = () => {
//Item sparator view
return (
<View
style={{
height: 0.3,
width: '90%',
backgroundColor: '#080808',
}}
/>
);
};
render() {
if (this.state.isLoading) {
//Loading View while data is loading
return (
<View style={{ flex: 1, paddingTop: 20 }}>
<ActivityIndicator />
</View>
);
}
return (
//ListView to show with textinput used as search bar
<View style={styles.viewStyle}>
<TextInput
style={styles.textInputStyle}
onChangeText={text => this.SearchFilterFunction(text)}
value={this.state.text}
underlineColorAndroid="transparent"
placeholder="Search Here"
/>
<FlatList
data={this.state.dataSource}
ItemSeparatorComponent={this.ListViewItemSeparator}
renderItem={({ item }) => (
<Text style={styles.textStyle}>{item.title}</Text>
)}
enableEmptySections={true}
style={{ marginTop: 10 }}
keyExtractor={(item, index) => index.toString()}
/>
</View>
);
}
}
const styles = StyleSheet.create({
viewStyle: {
justifyContent: 'center',
flex: 1,
marginTop: 40,
padding: 16,
},
textStyle: {
padding: 10,
},
textInputStyle: {
height: 40,
borderWidth: 1,
paddingLeft: 10,
borderColor: '#009688',
backgroundColor: '#FFFFFF',
},
});Run Code Online (Sandbox Code Playgroud)
这是我的解决方案:
您需要备份数据
this.state = {
data: [],
backup: []
}
Run Code Online (Sandbox Code Playgroud)
关于搜索方法
search = txt => {
let text = txt.toLowerCase()
let tracks = this.state.backup
let filterTracks = tracks.filter(item => {
if(item.name.toLowerCase().match(text)) {
return item
}
})
this.setState({ data: filterTracks })
}
Run Code Online (Sandbox Code Playgroud)
说明:当对您的数据调用 setState 时,它将更改为当前状态并且无法再次更改。
因此备份数据将处理过滤您的数据。
| 归档时间: |
|
| 查看次数: |
19491 次 |
| 最近记录: |