#react-native #react-native-flatlist #searchbar
#react-native #react-native-плоский список #панель поиска
Вопрос:
Я пытаюсь получить имена хранилищ из вложенного массива, но результатов не получаю, все работает нормально, но когда я набираю в строке поиска, я ничего не получаю (изображение ниже). Я снова вижу плоский список, как только удаляю то, что ввел. Я думаю, что проблема связана с данными, которые я возвращаю из фильтра. Вот что я сделал до сих пор.
const Purchases = () => {
const extractKey = ({purchases}) => purchases.toString();
const [search, setSearch] = useState(content);
function _searchFilterFunction(searchText, data) {
let newData = [];
if (searchText) {
newData = content.filter(function (item) {
item.purchases.filter(function (i) {
const itemData = i.name.toUpperCase();
const textData = searchText.toUpperCase();
return itemData.includes(textData);
})
});
setSearch([...newData]);
} else {
setSearch([...data]);
}
}
return (
<View style={styles.container}>
<TextInput
style={styles.textInputStyle}
placeholder="Search by Store"
onChangeText={(value) => {
_searchFilterFunction(value, content);
}}
/>
<FlatList
data={search}
renderItem={renderItem}
keyExtractor={extractKey}
/>
</View>
);
}
и вот массив:
let content = [
{
date: 'September 8, 2012',
total: 754,
purchases: [
{
name: 'Virgin Megastores',
time: '12:24',
price: 432,
icon: vms
},
{
name: 'Apple Store',
time: '13:43',
price: 322,
icon: apple
}
]
},
{
date: 'September 8, 2012',
total: 754,
purchases: [
{
name: 'Virgin Megastores',
time: '12:24',
price: 432,
icon: vms
},
{
name: 'Apple Store',
time: '13:43',
price: 322,
icon: apple
}
]
},
]
Ответ №1:
Ваша проблема заключается в том, как вы фильтруете свои данные.
newData = content.filter(function (item) {
item.purchases.filter(function (i) {
const itemData = i.name.toUpperCase();
const textData = searchText.toUpperCase();
return itemData.includes(textData);
});
});
filter
Функция ожидает функцию обратного вызова, которая возвращает логическое значение, чтобы определить, следует ли включать элемент или нет. Поскольку ваш contect.filter
вызов ничего не возвращает из своего обратного вызова, конечный newData
результат пуст.
Итак, давайте попробуем настроить код на что-то работающее
newData = content.filter(function (item) {
// check if any purchase has matches; and keep the filtered results
const filteredPurchases = item.purchases.filter(function (i) {
const itemData = i.name.toUpperCase();
const textData = searchText.toUpperCase();
return itemData.includes(textData);
});
// now let the parent know if it should include this item in the filter
// if the length is higher than zero, filter will include this item
return filteredPurchases.length;
});
В своем комментарии вы говорите, что хотите показать только применимые покупки. Давайте еще немного скорректируем код. Мы будем map
включать в контент только соответствующие покупки, а затем filter
все товары с соответствующими покупками
newData = content.map(function (item) {
// check if any purchase has matches; and keep the filtered results
const filteredPurchases = item.purchases.filter(function (i) {
const itemData = i.name.toUpperCase();
const textData = searchText.toUpperCase();
return itemData.includes(textData);
});
// now return a newly composed item with only applicable purchases
return {
...item,
purchases: filteredPurchases
};
}).filter(function (item) {
// now only keep items with applicable purchases.
return item.purchases.length
});
Комментарии:
1. Большое вам спасибо, но теперь возникла другая проблема: каждая покупка внутри массива содержимого содержит две покупки, как вы можете видеть, поэтому при поиске я получаю правильный результат в дополнение к другому, потому что массив — это то, что он возвращает. Как я могу получить каждую покупку отдельно?
2. Я немного расширил ответ, добавив для вас дополнительную логику.