我正在尝试使用搜索栏构建listView,但是似乎没有插入搜索栏的输入值并针对可用结果进行测试。
相反,它返回一个空的text: [ ]
。
我什至制作了一个空数组{ id: 5, text: " ", text2: "test" }
,这也不会返回任何结果。.
我现在想知道为什么搜索栏返回空?
在this.state.searchText
中确实检查了输入for loop
的值是否有任何结果。
for (i = 0; i < textLength; i++) {
if (aText[i].text === searchText) {
console.log("found: " + aText[i].text);
return aText[i];
}
}
我仍在学习,我是否解决了这个错误?我应该使用对象而不是数组吗?
为什么我没有得到任何结果?
我制作了example app,以便您可以在工作环境中查看代码。
任何建议,反馈或批评都非常受欢迎。
完整的示例代码
import React, { Component } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
import {
AppRegistry,
ListView,
View,
Text,
StyleSheet,
TextInput
} from "react-native";
// Row data (hard-coded)
const rows = [
{ id: 0, text: "View" },
{ id: 1, text: "Text" },
{ id: 2, text: "Image" },
{ id: 3, text: "ScrollView" },
{ id: 4, text: "ListView" },
{ id: 5, text: " ", text2: "test" }
];
// Row comparison function
const rowHasChanged = (r1, r2) => r1.id !== r2.id;
// DataSource template object
const ds = new ListView.DataSource({ rowHasChanged });
export default class App extends Component {
state = {
dataSource: ds.cloneWithRows(rows),
rows
};
setSearchText(event) {
const searchText = event.nativeEvent.text;
const textLength = this.state.rows.length;
const aText = this.state.rows;
const filteredTexts = this.state.rows.filter(checkText);
console.log("text: " + JSON.stringify(filteredTexts));
function checkText() {
var i;
for (i = 0; i < textLength; i++) {
if (aText[i].text === searchText) {
console.log("found: " + aText[i].text);
return aText[i];
}
}
}
this.setState({
searchText,
dataSource: this.state.dataSource.cloneWithRows(filteredTexts)
});
}
renderRow = rowData => {
return (
<Text style={styles.row}>
{rowData.text}
{rowData.text2}
</Text>
);
};
render() {
return (
<View style={styles.SearchBarContainer}>
<TextInput
placeholder="Search"
value={this.state.searchText}
onChange={this.setSearchText.bind(this)}
style={styles.searchBar}
underlineColorAndroid="#DD016B"
selectionColor="#DD016B"
/>
<ListView
style={styles.container}
dataSource={this.state.dataSource}
renderRow={this.renderRow}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1
},
row: {
padding: 15,
marginBottom: 5,
backgroundColor: "skyblue"
}
});
AppRegistry.registerComponent("App", () => App);
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
答案 0 :(得分:2)
您似乎没有保留searchText的状态
state = {
dataSource: ds.cloneWithRows(rows),
rows,
searchText:"" //ADD THIS
};
答案 1 :(得分:2)
这非常简单,您无需使用for循环即可从数组中进行搜索。
您只需通过对象中的文本匹配过滤即可获得所需的结果。
我已修复您的示例应用程序,您可以对其进行测试。
只需用此行const filteredTexts = this.state.rows.filter(record => record.text.toLowerCase().match(searchText));
替换循环函数
答案 2 :(得分:1)
我建议使用FlatList,因为已描述了ListView。我已经稍微重写了您的代码,您可以在Expo Snack上进行检查,也可以只看下面的代码
import React, { Component } from "react";
import {
AppRegistry,
ListView,
View,
Text,
StyleSheet,
TextInput,
FlatList
} from "react-native";
// Row data (hard-coded)
const rows = [
{ id: 0, text: "View" },
{ id: 1, text: "Text" },
{ id: 2, text: "Image" },
{ id: 3, text: "ScrollView" },
{ id: 4, text: "ListView" },
{ id: 5, text: " ", text2: "test" }
];
export default class App extends Component {
state = {
rows,
filteredRows: rows,
};
setSearchText(event) {
const searchText = event.nativeEvent.text;
const textLength = this.state.rows.length;
const filteredTexts = this.state.rows.filter(row => {
return row.text.indexOf(searchText) !== -1;
});
console.log("text: " + JSON.stringify(filteredTexts));
this.setState({
searchText,
filteredRows: filteredTexts
});
}
renderRow = rowData => {
return (
<Text style={styles.row}>
{rowData.item.text}
{rowData.item.text2}
</Text>
);
};
render() {
return (
<View style={styles.SearchBarContainer}>
<TextInput
placeholder="Search"
value={this.state.searchText}
onChange={this.setSearchText.bind(this)}
style={styles.searchBar}
underlineColorAndroid="#DD016B"
selectionColor="#DD016B"
/>
<FlatList
style={styles.container}
data={this.state.filteredRows}
renderItem={this.renderRow}
/>
</View>
);
}
}
const styles = StyleSheet.create({
SearchBarContainer: {
marginTop: 40,
flex: 1
},
row: {
padding: 15,
marginBottom: 5,
backgroundColor: "skyblue",
color: 'black',
},
});