Reactjs 在ListView中搜索

Reactjs 在ListView中搜索,reactjs,react-native,Reactjs,React Native,我把这本书通读了一遍 我正在尝试通过体验和构建应用程序来学习 我当前的问题发生在我创建了一个静态ListView并尝试对其进行过滤之后。我发现了另一个人是如何做到这一点的,但我得到了一个错误: undefined不是对象(正在计算'this.state.rows.length') 我认为行定义如下: state = { dataSource: ds.cloneWithRows(rows) } 所以我对错误的来源感到困惑 应用程序文件 import React, { Comp

我把这本书通读了一遍

我正在尝试通过体验和构建应用程序来学习

我当前的问题发生在我创建了一个静态ListView并尝试对其进行过滤之后。我发现了另一个人是如何做到这一点的,但我得到了一个错误:

undefined不是对象(正在计算'this.state.rows.length')

我认为
定义如下:

    state = {
    dataSource: ds.cloneWithRows(rows)
  }
所以我对错误的来源感到困惑

应用程序文件

import React, { Component } from 'react';

import { 
    AppRegistry,
    ListView, 
    View, 
    Text, 
    StyleSheet, 
    Image, 
    Button, 
    TouchableOpacity, 
    TextInput, 
    ScrollView,
    Icon,
} from 'react-native';

import { createStackNavigator, } from 'react-navigation';

const image1 = require('./assets/card-0.png')
const image2 = require('./assets/card-2.png')
const image3 = require('./assets/card-3.png')
const image4 = require('./assets/card-4.png')
const image5 = require('./assets/card-5.png')

// Row data (hard-coded)
const rows = [
  {id: 0, club: 'Club Air', genre: 'Hip Hop / R&B', image: image1},
  {id: 1, club: 'Abe', genre: 'Hip Hop / R&B', image: image2},
  {id: 2, club: 'John Doe', genre: 'Hip Hop / R&B', image: image3},
  {id: 3, club: 'Encore', genre: 'Hip Hop / R&B', image: image4},
  {id: 4, club: 'Jimmy Whoo', genre: 'Hip Hop / R&B', image: image5},
]

// Row comparison function
const rowHasChanged = (r1, r2) => r1.id !== r2.id

// DataSource template object
const ds = new ListView.DataSource({rowHasChanged})

export class HomeScreen extends Component {
    static navigationOptions = {
        // title: ' Alpha',
        header: null,
    };

  state = {
    dataSource: ds.cloneWithRows(rows)
  }

  setSearchText(event){
    const searchText = event.nativeEvent.text;

    clubsLength = this.state.rows.length;
    aClub= this.state.rows;

    const filteredClubs = this.state.rows.filter(checkTitle);
    console.log("clubs: " + JSON.stringify(filteredClubs));

    function checkClub() {
        for(i=0;i<clubsLength;i++){
          if(aClub[i].club === searchText){
            console.log("found:  " + aClub[i].club);
            return aClub[i];
          }
        }
    }

    this.setState({
        searchText,
        dataSource: this.state.dataSource.cloneWithRows(filteredClubs),
    });
  }

  renderRow = (rowData) => { 
    return (

        <View style={styles.card}>
            <TouchableOpacity onPress={() => this.props.navigation.navigate('Details')}> 
                <View style={styles.innerCard}>
                    <Image 
                        style={styles.imageCard} 
                        source={rowData.image}
                    />
                    <Text style={styles.innerText}>
                        {rowData.club}
                    </Text>
                </View>
                <View style={styles.outerCard}>
                    <Text style={styles.outerText}>
                        {rowData.genre}
                    </Text>
                    <Text style = {styles.outerTexts}>
                       View
                    </Text>
                </View>
            </TouchableOpacity>
        </View>
    )
  }


  render() {
    return (

        <ScrollView style={styles.container}>
            <View style={styles.SearchBarContainer}>
                <TextInput  
                placeholder="Search"
                value={this.state.searchText}
                onChange={this.setSearchText.bind(this)}
                style={styles.searchBar}
                underlineColorAndroid="#DD016B"
                selectionColor="#DD016B"
                />
            </View>
            <ListView
            style={styles.listContainer}
            dataSource={this.state.dataSource}
            renderRow={this.renderRow}
            />
        </ScrollView>

    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'black',
    width:'100%',
    // height: 299,

  },
  SearchBarContainer: {
    justifyContent: 'center',
    alignItems: 'center'
  },
  listContainer: {
    flex: 1,
    backgroundColor: 'black',
    width:'100%',
    // height: 299,
  },
  button: {
    backgroundColor: 'transparent',
    width: '50%',
  },
  textInput: {
    height: 30,
    borderWidth: 1,
    borderColor: '#DD016B',
    marginBottom: 10,
    marginHorizontal: 10,
  },
  searchBar: {
    textAlign: 'center',
    height: 40, 
    width:200,
    color: '#DD016B',
    borderColor: '#DD016B', 
    // selectionColor: '#DD016B',
    // borderWidth: 1,
    // borderRadius: 5,
    marginBottom:20,
    marginTop: 20,
    justifyContent: 'center',
  },
  card: {
    marginBottom: 15,
  },
  innerCard: {
    height:110,
  },
  imageCard: {
    width: 500,
    height: 150,
    paddingTop: 0,
    paddingBottom: 0, 
    marginBottom:0, 
    marginTop: 0,
  },
  innerText: {
    color: 'white',
    marginBottom: 0,
    fontSize: 35,
    position: 'absolute',
    top: 100,
  },
  outerText: {
    color: '#DD016B',
    marginBottom: 0,
    marginTop: 50,
    width: 100,
  },
})

AppRegistry.registerComponent('App', () => App)

export default createStackNavigator({
  Home: {
    screen: HomeScreen,
  },
}, {
    initialRouteName: 'Home',
});
import React,{Component}来自'React';
导入{
评估学,
ListView,
看法
文本,
样式表,
形象,,
按钮
可触摸不透明度,
文本输入,
滚动视图,
偶像
}从“反应本机”;
从“react navigation”导入{createStackNavigator,};
const image1=require(“./assets/card-0.png”)
const image2=require(“./assets/card-2.png”)
const image3=require(“./assets/card-3.png”)
const image4=require(“./assets/card-4.png”)
const image5=require(“./assets/card-5.png”)
//行数据(硬编码)
常量行=[
{id:0,俱乐部:'club Air',流派:'Hip Hop/R&B',图片:image1},
{id:1,俱乐部:'Abe',流派:'Hip Hop/R&B',图片:image2},
{id:2,俱乐部:'John Doe',流派:'Hip Hop/R&B',图片:image3},
{id:3,俱乐部:'Encore',流派:'Hip Hop/R&B',图片:image4},
{id:4,俱乐部:'Jimmy Whoo',流派:'Hip Hop/R&B',图片:image5},
]
//行比较函数
常量rowHasChanged=(r1,r2)=>r1.id!==r2.id
//数据源模板对象
const ds=new ListView.DataSource({rowHasChanged})
导出类主屏幕扩展组件{
静态导航选项={
//标题:“阿尔法”,
标题:null,
};
状态={
数据源:ds.cloneWithRows(rows)
}
setSearchText(事件){
const searchText=event.nativeEvent.text;
clubsLength=this.state.rows.length;
aClub=this.state.rows;
const filteredClubs=this.state.rows.filter(checkTitle);
log(“clubs:+JSON.stringify(filteredClubs));
函数checkClub(){
对于(i=0;i{
返回(
this.props.navigation.navigate('Details')}>
{rowData.club}
{rowData.genre}
看法
)
}
render(){
返回(
)
}
}
const styles=StyleSheet.create({
容器:{
弹性:1,
背景颜色:“黑色”,
宽度:'100%',
//身高:299,
},
SearchBarContainer:{
为内容辩护:“中心”,
对齐项目:“中心”
},
列表容器:{
弹性:1,
背景颜色:“黑色”,
宽度:'100%',
//身高:299,
},
按钮:{
背景色:“透明”,
宽度:“50%”,
},
文本输入:{
身高:30,
边框宽度:1,
边框颜色:“#DD016B”,
marginBottom:10,
marginHorizontal:10,
},
搜索栏:{
textAlign:'中心',
身高:40,
宽度:200,
颜色:“#DD016B”,
边框颜色:“#DD016B”,
//选择颜色:“#DD016B”,
//边框宽度:1,
//边界半径:5,
marginBottom:20,
玛金托普:20,
为内容辩护:“中心”,
},
卡片:{
marginBottom:15,
},
内部卡:{
身高:110,
},
图像卡:{
宽度:500,
身高:150,
paddingTop:0,
填充底部:0,
marginBottom:0,
玛金托普:0,
},
内部文本:{
颜色:'白色',
marginBottom:0,
尺码:35,
位置:'绝对',
前100名,
},
外部文本:{
颜色:“#DD016B”,
marginBottom:0,
玛金托普:50,
宽度:100,
},
})
AppRegistry.registerComponent('App',()=>App)
导出默认createStackNavigator({
主页:{
屏幕:主屏幕,
},
}, {
initialRouteName:“主页”,
});
出现错误的原因是您试图从您的状态读取
,但是
是组件外部的数组

您可以引用状态之外的
数组,也可以在创建数组时将其置于状态

示例

import React, { Component } from 'react';

import { 
    AppRegistry,
    ListView, 
    View, 
    Text, 
    StyleSheet, 
    Image, 
    Button, 
    TouchableOpacity, 
    TextInput, 
    ScrollView,
    Icon,
} from 'react-native';

import { createStackNavigator, } from 'react-navigation';

const image1 = require('./assets/card-0.png')
const image2 = require('./assets/card-2.png')
const image3 = require('./assets/card-3.png')
const image4 = require('./assets/card-4.png')
const image5 = require('./assets/card-5.png')

// Row data (hard-coded)
const rows = [
  {id: 0, club: 'Club Air', genre: 'Hip Hop / R&B', image: image1},
  {id: 1, club: 'Abe', genre: 'Hip Hop / R&B', image: image2},
  {id: 2, club: 'John Doe', genre: 'Hip Hop / R&B', image: image3},
  {id: 3, club: 'Encore', genre: 'Hip Hop / R&B', image: image4},
  {id: 4, club: 'Jimmy Whoo', genre: 'Hip Hop / R&B', image: image5},
]

// Row comparison function
const rowHasChanged = (r1, r2) => r1.id !== r2.id

// DataSource template object
const ds = new ListView.DataSource({rowHasChanged})

export class HomeScreen extends Component {
    static navigationOptions = {
        // title: ' Alpha',
        header: null,
    };

  state = {
    dataSource: ds.cloneWithRows(rows)
  }

  setSearchText(event){
    const searchText = event.nativeEvent.text;

    clubsLength = this.state.rows.length;
    aClub= this.state.rows;

    const filteredClubs = this.state.rows.filter(checkTitle);
    console.log("clubs: " + JSON.stringify(filteredClubs));

    function checkClub() {
        for(i=0;i<clubsLength;i++){
          if(aClub[i].club === searchText){
            console.log("found:  " + aClub[i].club);
            return aClub[i];
          }
        }
    }

    this.setState({
        searchText,
        dataSource: this.state.dataSource.cloneWithRows(filteredClubs),
    });
  }

  renderRow = (rowData) => { 
    return (

        <View style={styles.card}>
            <TouchableOpacity onPress={() => this.props.navigation.navigate('Details')}> 
                <View style={styles.innerCard}>
                    <Image 
                        style={styles.imageCard} 
                        source={rowData.image}
                    />
                    <Text style={styles.innerText}>
                        {rowData.club}
                    </Text>
                </View>
                <View style={styles.outerCard}>
                    <Text style={styles.outerText}>
                        {rowData.genre}
                    </Text>
                    <Text style = {styles.outerTexts}>
                       View
                    </Text>
                </View>
            </TouchableOpacity>
        </View>
    )
  }


  render() {
    return (

        <ScrollView style={styles.container}>
            <View style={styles.SearchBarContainer}>
                <TextInput  
                placeholder="Search"
                value={this.state.searchText}
                onChange={this.setSearchText.bind(this)}
                style={styles.searchBar}
                underlineColorAndroid="#DD016B"
                selectionColor="#DD016B"
                />
            </View>
            <ListView
            style={styles.listContainer}
            dataSource={this.state.dataSource}
            renderRow={this.renderRow}
            />
        </ScrollView>

    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'black',
    width:'100%',
    // height: 299,

  },
  SearchBarContainer: {
    justifyContent: 'center',
    alignItems: 'center'
  },
  listContainer: {
    flex: 1,
    backgroundColor: 'black',
    width:'100%',
    // height: 299,
  },
  button: {
    backgroundColor: 'transparent',
    width: '50%',
  },
  textInput: {
    height: 30,
    borderWidth: 1,
    borderColor: '#DD016B',
    marginBottom: 10,
    marginHorizontal: 10,
  },
  searchBar: {
    textAlign: 'center',
    height: 40, 
    width:200,
    color: '#DD016B',
    borderColor: '#DD016B', 
    // selectionColor: '#DD016B',
    // borderWidth: 1,
    // borderRadius: 5,
    marginBottom:20,
    marginTop: 20,
    justifyContent: 'center',
  },
  card: {
    marginBottom: 15,
  },
  innerCard: {
    height:110,
  },
  imageCard: {
    width: 500,
    height: 150,
    paddingTop: 0,
    paddingBottom: 0, 
    marginBottom:0, 
    marginTop: 0,
  },
  innerText: {
    color: 'white',
    marginBottom: 0,
    fontSize: 35,
    position: 'absolute',
    top: 100,
  },
  outerText: {
    color: '#DD016B',
    marginBottom: 0,
    marginTop: 50,
    width: 100,
  },
})

AppRegistry.registerComponent('App', () => App)

export default createStackNavigator({
  Home: {
    screen: HomeScreen,
  },
}, {
    initialRouteName: 'Home',
});
导出类主屏幕扩展组件{
静态导航选项={
标题:空
};
状态={
数据源:ds.cloneWithRows(rows),
排
};
// ...
}

您的
主屏幕
组件在其状态下没有
。@您可以向我解释一下,或者在哪里可以找到它来解释如何执行此操作?您的
数组作为组件外部的变量。如果您希望它处于您的状态,您可以编写例如
状态={dataSource:ds.cloneWithRows(rows),rows}
或引用
rows
而不是
this.state.rows
@Tholle,这似乎有帮助。应用程序似乎在搜索,但找不到标题,但我会继续进行疑难解答,并在文档中查找。您可以将其作为答案发布,以便我可以关闭此问题。谢谢!)你知道为什么我在搜索时没有得到任何结果吗?例如:club air。我只是得到一个空屏幕。@Salman我不太确定。可能值得创建一个in,例如,并用它创建一个新问题。谢谢CodeSandbox似乎非常有用!我会看看是否可以解决它