J'essaye de rechercher par une flatlist basée sur un texte de barre de recherche. Le problème que je rencontre est que lorsque l'utilisateur utilise des fautes de frappe ... il dit qu'il voulait saisir "burger" mais tapé "burget" par erreur, il ne renvoie rien comme il se doit. Lorsque l'utilisateur supprime le "t", il doit alors restituer à nouveau la liste standard avec le dernier texte correspondant à la partie "renverser".
remarque: en utilisant la barre de recherche react-native-elements qui me permet d’appeler le texte avec e ou event.
Ce que j'ai jusqu'à présent dans le fichier 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>
puis le 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>
)
}
}
J'ai essayé quelques autres façons en vain. De plus, les seules solutions que j'ai vues travailler pour React Native sont celles de ListView, qui seront amorties avec le temps. J'essaie donc de faire cela avec le nouveau composant FlatList.
Merci de votre aide!
Je suis tombé sur le même problème aujourd'hui en essayant d'implémenter une fonction de filtrage/recherche sur le nouveau composant FlatList. Voici comment j'ai réussi à le résoudre:
En créant un autre élément dans l'état du composant parent appelé noData, vous pouvez le définir sur true lorsqu'il n'y a aucun résultat correspondant à votre recherche, puis restituer votre FlatList de manière conditionnelle.
Mon implémentation est légèrement différente de la vôtre, mais si je devais ajuster votre code, il ressemblerait à ceci:
Fonction 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
})
}
}
Puis passez le noData bool à votre composant TruckList:
<TruckList getTruck={(truck) => this.setTruck(truck)}
truckScreen={this.truckScreen} data={this.state.data} noData={this.state.noData}/>
Rendez ensuite votre FlatList dans le composant TruckList uniquement s'il y a des résultats:
<List style={styles.list}>
{this.props.noData ? <Text>NoData</Text> : <FlatList {...} />}
</List>
Cela devrait alors prendre en charge le traitement des erreurs de frappe des utilisateurs - car il rendra à nouveau la liste plate dès qu’il n’y aura aucun résultat, et se souviendra de l’état de la recherche précédent lorsque vous supprimerez l’erreur de frappe.
Dis moi si ça aide!
Mise à jour:Ce blog peut vous aider à mieux comprendre la recherche dans une FlatList.
FYI: Si vous avez d’énormes données en ligne, vous pouvez également utiliser algolia .
J'ai ajusté le code ci-dessus pour que cela fonctionne correctement. La raison en est que lorsque l'utilisateur supprime le dernier caractère incorrect, le code recherche cette nouvelle chaîne dans une liste de recherche précédente (état) qui ne contient pas tous les objets, bien qu'il ait dû effectuer une recherche dans une liste complète disponible. Donc, j'ai deux liste maintenant. Le premier contient la liste complète des objets et le second ne contient que la liste rendue des objets qui est modifiée lors de la recherche.
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
})
}
}
Voici ma solution:
Vous devez avoir une sauvegarde de vos données
this.state = {
data: [],
backup: []
}
sur la méthode de recherche
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 })
}
Explication: lorsque vous appelez setState sur vos données, il passe à l'état actuel et ne peut plus être modifié.
Les données de sauvegarde se chargeront donc de filtrer vos données.
FYI: data
est la subtext
à rechercher, il s'agit d'une recherche de base implémentée car les données à rechercher sont examinées dans chaque élément de la liste d'un tableau qui est une copie du array/array
réel de objects
et finalement l'état est défini, que la correspondance trouvée ou non entre 0
à (actualArray.length-1
) et que la variable temporaire arrayData
soit rendue s'il existe au moins une correspondance, sinon la variable actualArray
est rendue
implementSearch(data) {
temp = [];
var count = 0;
var searchData = data.toUpperCase();
var arr = this.state.personDetail;
for (var i = 0; i < arr.length; i++) {
var actualData = arr[i].name.toUpperCase();
if (actualData.includes(searchData)) {
temp.Push(arr[i]);
count++;
}
}
this.setState({
tempArray: temp,
matches: count,
searchValue: data
});
}
Espoir cela aide