搜索输入在ListView中显示为空

时间:2018-11-13 09:11:37

标签: reactjs react-native

我正在尝试使用搜索栏构建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);

3 个答案:

答案 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',
  },
});