Это действительно хорошее начало.Однако есть несколько проблем с вашим кодом.Итак, давайте пройдемся по нему и посмотрим, где мы можем сделать некоторые улучшения.
Конструктор
Во-первых, в своем конструкторе вы делаете данные объектом, а не массивом.Плоские списки не работают с объектами, которые они работают с массивами, поэтому это немедленно вызовет у вас проблемы.Вы действительно должны удалить {}
из restaurantList
.
constructor() {
super();
this.state = {
loading: false,
data: {restaurantList}, // You shouldn't have {} around the restaurantList
error: null,
};
this.arrayholder = []; // we also don't need this
}
Вам следует обновить конструктор до этого
constructor (props) {
super(props);
this.state = {
loading: false,
data: restaurantList, // notice we have no {} around restaurantList
error: null,
value: ''
};
}
renderHeader
В вашей функции renderHeader
вы используете onChange
вместо onChangeText
.onChange
возвращает объект, но вы хотите, чтобы text
был помещен в строку поиска.Вам нужно обновить функцию renderHeader
, чтобы она была такой:
renderHeader = () => {
return (
<SearchBar
placeholder="Type..."
value={this.state.value}
onChangeText={text => this.searchFilterFunction(text)} // now we are using the correct function to capture the text
/>
);
};
searchFilterFunction
Есть несколько проблем с этой функцией.Сначала вы смотрите на this.arrayholder
, который пуст.На самом деле нам не нужен дополнительный массив для хранения данных, поскольку мы можем просто использовать restaurantList
, который мы импортировали ранее.Во-вторых, вы используете indexOf
для строки, лучше использовать includes
.
searchFilterFunction = text => {
this.setState({
value: text
});
const newData = restaurantList.filter(item => {
const itemData = `${item.name.toUpperCase()} ${item.type.toUpperCase()}`;
const textData = text.toUpperCase();
return itemData.includes(textData); // this will return true if our itemData contains the textData
});
this.setState({
data: newData
});
};
FlatList
В вашем FlatList вы должны использовать extraData
prop, поскольку это позволит FlatList обновляться при изменении базовых данных.Вы также должны добавить keyExtractor
.
<FlatList
keyExtractor={(item, index) => `${index}`}
extraData={this.state} // <- add this prop
data={this.state.data}
renderItem={({ item }) => (
<Text>{item.name} {item.type}</Text>
)}
ItemSeparatorComponent={this.renderSeparator}
ListHeaderComponent={this.renderHeader}
/>
Собрать все вместе
Так что, если мы соберем все это вместе, добавим макет данных, чтобы мы могли проверить, работает ли он.Мы должны получить что-то вроде этого.
// mock the data as you didn't provide an example
const restaurantList = [
{
type: 'Italian',
name: 'DiMaggio'
},
{
type: 'Greek',
name: 'Athena'
}
];
export default class SearchScreen extends React.Component {
static navigationOptions = {
title: 'Search for Restaurants'
};
constructor (props) {
super(props);
this.state = {
loading: false,
data: restaurantList,
error: null,
value: ''
};
}
renderSeparator = () => {
return (
<View
style={{
height: 1,
width: '86%',
backgroundColor: '#CED0CE',
marginLeft: '14%'
}}
/>
);
};
searchFilterFunction = text => {
this.setState({
value: text
});
const newData = restaurantList.filter(item => {
const itemData = `${item.name.toUpperCase()} ${item.type.toUpperCase()}`;
const textData = text.toUpperCase();
return itemData.includes(textData);
});
this.setState({
data: newData
});
};
renderHeader = () => {
return (
<SearchBar
placeholder="Type..."
value={this.state.value}
onChangeText={text => this.searchFilterFunction(text)}
/>
);
};
render () {
if (this.state.loading) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<ActivityIndicator />
</View>
);
} else {
return (
<View style={styles.container}>
<FlatList
keyExtractor={(item, index) => `${index}`}
extraData={this.state}
data={this.state.data}
renderItem={({ item }) => (
<Text>{item.name} {item.type}</Text>
)}
ItemSeparatorComponent={this.renderSeparator}
ListHeaderComponent={this.renderHeader}
/>
</View>
);
}
}
}
Закуска
Вы можете увидеть, как он работает на следующей закуске https://snack.expo.io/@andypandy/flatlist-with-search