Поиск через ListView

Я прочитал реагировать на собственные документы и реагировать родной экспресс.

Я пытаюсь научиться реагировать на собственный опыт работы с корытами и создавать приложения.

Моя текущая проблема возникает после того, как я создал статический ListView и попытался отфильтровать его. Я нашел пример того, как другой смог этого добиться, но получаю сообщение об ошибке:

undefined is not an object (evaluating 'this.state.rows.length')

Я, хотя rows был определен в:

    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.info("clubs: " + JSON.stringify(filteredClubs));

    function checkClub() {
        for(i=0;i<clubsLength;i++){
          if (aClub[i].club === searchText){
            console.info("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',
});

В вашем компоненте HomeScreen нет rows в своем состоянии.

Tholle 11.11.2018 22:23

@Tholle Не могли бы вы объяснить мне, или где я могу найти объяснение, как это сделать?

Salman 11.11.2018 23:13

У вас есть массив rows как переменная вне вашего компонента. Если вы хотите, чтобы это было в вашем состоянии, вы можете написать, например, state = { dataSource: ds.cloneWithRows(rows), rows } или ссылка rows вместо this.state.rows.

Tholle 11.11.2018 23:16

@Tholle, похоже, это помогло. Кажется, что приложение ищет, но не может найти название, но я продолжу устранять неполадки и просматривать документы. Вы можете опубликовать его как ответ, чтобы я мог закрыть этот вопрос. Спасибо! :)

Salman 12.11.2018 10:52
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
4
96
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Причина, по которой вы получаете свою ошибку, заключается в том, что вы пытаетесь прочитать rows из своего состояния, но rows - это массив вне вашего компонента.

Вы можете либо сослаться на массив rows, который находится за пределами вашего состояния, либо перевести массив в состояние при его создании.

Пример

export class HomeScreen extends Component {
  static navigationOptions = {
    header: null
  };

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

  // ...
}

Вы случайно не знаете, почему я не получаю результатов при поиске? Пример: клубный воздух. У меня просто пустой экран.

Salman 12.11.2018 10:54

@ Салман Я не совсем уверен. Возможно, стоит создать Минимальный, полный и проверяемый пример, например, в CodeSandbox и создайте новый вопрос с этим.

Tholle 12.11.2018 10:55

Спасибо, CodeSandbox кажется очень полезным! Я посмотрю, смогу ли я снять это

Salman 12.11.2018 10:56

Другие вопросы по теме