Я пытаюсь реализовать словарь в своем приложении. Для этого я получаю ответ api, который содержит данные для словаря.
Ответ api будет основан на вводе, введенном пользователем. Если я наберу букву a, будет получен соответствующий результат. Но при дальнейшем вводе полного слова, скажем, adhaar, я ожидаю, что отобразит только этот частный элемент. в моем случае, что бы я ни набирал в поле поиска, результат будет таким же даже после того, как будет набрано полное слово. Кроме того, я не получаю результат слова, которое я набираю. Я слежу за этим документом
Пожалуйста, помогите мне разобраться в моей ошибке. Что я делаю не так? Пожалуйста, помогите. Ниже приведен мой код.
constructor(props) {
super(props);
this.state = {
loading: false,
data:[]
};
this.arrayholder = [];
}
searchFilterFunction = text =>{
this.setState({ text });
console.info(this.state.text);
fetch('xxxxxx', {
method:'POST',
headers: {
'Accept': 'application/json'
},
body:JSON.stringify({
s:text,
loading:false
})
}).then((response) => response.json())
.then((responseData) => {
this.setState({
data:responseData.data
})
this.arrayholder = responseData.data
})
.catch(error => {
this.setState({ error, loading: false });
});
const newData = this.arrayholder.filter(item => {
const itemData = `${item.post_title}`;
const textData = text;
return itemData.indexOf(textData) > -1;
this.setState({ data: newData });
});
}
<Container>
<Header>
<Item>
<Input placeholder = "Search"
onChangeText = {text => this.searchFilterFunction({text})}
/>
</Item>
</Header>
...
...
<List containerStyle = {{ borderTopWidth: 0, borderBottomWidth: 0 }}>
<FlatList
data = {this.state.data}
renderItem = {({ item }) => (
<Text>{item.post_title}</Text>
)}
keyExtractor = {(item, index) => index.toString()}
ItemSeparatorComponent = {this.renderSeparator}
/>
</List>
<Container>
Вот так будет экран вывода https://i.stack.imgur.com/gXhTb.png
Любая помощь приветствуется. Спасибо!



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Это связано с проблемой объема. У вас есть код, выполняющийся в асинхронном режиме, и код, выполняющийся после этого, в зависимости от асинхронного результата. Это не сработает для вас.
Есть несколько проблем с функцией searchFilter.
Когда вы создаете newData, setState записывается в фильтре после оператора return. Он никогда не будет вызван, поэтому вы никогда не обновляете свое состояние.
Вы также, что кажется ненужным, вызываете setState несколько раз. Я думаю, тебе нужно всего лишь дважды вызвать. Один раз, когда данные были загружены, и один раз, когда данные не загружаются.
Вот обновленный searchFilterFunction, он должен дать вам некоторые идеи о том, как вы могли бы исправить свой код.
searchFilterFunction = text =>{
console.info(text);
fetch(
...
)
.then((response) => response.json())
.then((responseData) => {
const filteredData = responseData.data.filter(item => {
const itemData = `${item.post_title}`;
const textData = text;
return itemData.indexOf(textData) > -1;
});
this.setState({
data: filteredData,
text
});
})
.catch(error => {
this.setState({ error, loading: false, text });
});
}
Я удалил setState для текста в начале, вам нужно установите его здесь, так как это приведет к повторному рендерингу.
В .then((responseData) => ... ) я обновил его, так что вы сразу выполняете фильтрацию на responseData.data, а затем сохраняете filteredData и text в состояние.
Я удалил настройку this.arrayholder. Я не думаю, что она вам действительно нужна, если вы не используете ее где-либо еще.
В ваш FlatList я бы добавил опору extraData
A marker property for telling the list to re-render (since it implements PureComponent)
<FlatList
...
extraData = {this.state}
...
>
Надеюсь, этого будет достаточно, чтобы вы исправили свой код.
Вы вводите правильный поисковый текст в searchFilterFunction? Вы пробовали выйти из responseData, чтобы узнать, получаете ли вы ответ от сервера? Если да, то получаете ли вы ответ, пробовали ли вы выйти из filterData, чтобы увидеть, есть ли там какие-то совпадения?
Я пробовал console.info(this.state.data) в render, но получаю пустой массив. Также я попробовал console.info(itemData), результат был таким же, как и до того, как не вернулся соответствующий элемент.
Собственно filteredData не существует ли это data?
Шаги по исправлению этого довольно просты. Вам необходимо знать, передаете ли вы правильный поисковый текст в searchFilterFunction. Затем вам нужно убедиться, что responseData - это то, что вы ожидаете от вызова fetch. Затем вам нужно отфильтровать этот ответ, чтобы он соответствовал строке текста поиска. Если вы не собираетесь их проверять, я больше не могу вам помочь.
Да, я пробовал и то, и другое. searchFilterFunction дает ожидаемый результат. Я попытался утешить отфильтрованный результат. Он идеальный.
Фактическая проблема, с которой я столкнулся, - не могу выполнить этот this.setState({data: data}). После того, как я попытался отобразить this.state.data в FlatList, я получаю сообщение об ошибке cannot read property data of null.
Потому что я получу значение в data только после выполнения функции фильтра, правильно? Поэтому при вызове выборки состояние изначально будет нулевым. Это может быть проблемой?
Я только что исправил опечатку в своем коде. Очевидно, что фильтр должен быть `const filterData = ...`, а не const data = ....
Да, теперь одна проблема решена, поиск идет нормально. Но только по первому слову. Если я наберу любые слова, начинающиеся с алфавита B, результат не будет отображаться. Но я проверил с помощью Postman, чтобы убедиться, что результат идет. любая проблема.Но не работает в моем коде
Измените return itemData.indexOf(textData) > -1; на что-то вроде return itemData.includes(textData);w3schools.com/jsref/jsref_includes.asp
Спасибо за ответ. Я попробовал ваш метод, но рендеринг не работает. Не могу найти результатов поиска :(