Estoy tratando de buscar a través de un flatlist basado en una barra de búsqueda de texto. El problema que yo postulo es que cuando el usuario mistypes…dicen que querían tipo de «hamburguesa» sino escribir «burget» por error, a continuación, devuelve nada de lo que debería. Cuando el usuario elimina la «t», a continuación, debe volver a renderizar el flatlist de nuevo con el último texto de coincidencia de la «burge» parte.

nota: el uso de reaccionar-nativo-elementos de la barra de búsqueda que me permite que le llame el texto con sólo e o evento.

Lo que tengo hasta ahora en el Main.js archivo:

searchText = (e) => {
    let text = e.toLowerCase();
    let trucks = this.state.data;

    //search by food truck name
    let filteredName = trucks.filter((truck) => {
      return truck.name.toLowerCase().match(text); 
    });

    //if no match and text is empty
    if(!text || text === '') {
      console.log('change state');
        this.setState({
          data: initial
        });
      }
    //if no name matches to text output
    else if(!Array.isArray(filteredName) && !filteredName.length) {
      console.log("not name");
      this.setState({
        data: [],
      });
    }
    //if name matches then display
    else if(Array.isArray(filteredName)) {
      console.log('Name');
      this.setState({
        data: filteredName,
      });
    }
   };

<View style={styles.container}>
  <SearchBar
    round
    lightTheme
    containerStyle={styles.search}
    ref="search"
    textInputRef="searchText"
    onChangeText={this.searchText.bind(this)}
    placeholder='Search by Truck Name...'
   />
   <TruckList getTruck={(truck) => this.setTruck(truck)} truckScreen={this.truckScreen} data={this.state.data}/>
</View>

a continuación, el TruckList.JS:

export default class TruckList extends Component {
    //rendering truck screen
    renderTruckScreen = (item) => {
        this.props.truckScreen();
        this.props.getTruck(item);
    }

    render() {
        return(
            <List style={styles.list}>
                <FlatList
                    data={this.props.data}
                    renderItem={({ item }) => (
                        <ListItem
                            roundAvatar
                            avatar={{uri: item.pic1}}
                            avatarStyle={styles.avatar}
                            title={item.name}
                            titleStyle={styles.title}
                            subtitle={
                                <View style={styles.subtitleView}>
                                    <Text style={styles.subtitleFood}>{item.food}</Text>
                                    <View style={styles.subtitleInfo}>
                                        <Icon 
                                            name="favorite"
                                            size={20}
                                            color={"#f44336"}
                                            style={styles.subtitleFavorite}
                                        />
                                        <Text style={styles.subtitleFavoriteText}>{item.favorited} favorited</Text>
                                    </View>
                                </View>
                            }
                            onPress={() => this.renderTruckScreen(item)}
                        />
                    )}
                    keyExtractor={(item) => item.uid}
                    ListFooterComponent={this.footer}
                />
            </List>
        )
      }
    }

He intentado un par de otras maneras sin éxito. También las únicas soluciones que he visto trabajando para Reaccionar Nativos son con ListView que serán amortizados en el tiempo. Así que estoy tratando de hacer esto con la nueva FlatList Componente.

Gracias por su ayuda!

  • ¿cuál es el problema? Es re-render no sucede cuando el usuario modifica el texto de búsqueda?
  • el problema es que cuando el usuario mistypes los datos se establece a [] y luego, cuando se elimine la escritura de los datos debe ser restablecer el último estado de la búsqueda…simplemente no han descubierto la manera de que podría funcionar. Posiblemente la configuración de estado anterior, a continuación, llamar de alguna manera?
  • Cuando el usuario mistypes, su resultado está vacía [ ] pero cuando el usuario se corrige, ¿no obtener los resultados de nuevo ? Supongo que onChange, obtener los resultados cada vez.
  • Se debe recuperar de nuevo los resultados, sin embargo, no es así. La escritura establece que los datos [] pero luego, cuando se elimine la escritura de los datos es todavía []. Cuando me de registro de la consola durante el proceso de escribir lo que pasa es que después de la supresión de la escritura se remonta a la else if(Array.isArray(filteredName)) sin embargo, no hay datos para restablecer el estado o algo así
  • Puede ser que usted necesita ajustar su orden condicional. Mi opinión es buscar y almacenar los resultados en cada búsqueda de texto cambio, en lugar de basarse en el conjunto de resultados anterior.
  • bien, supongo que tu método es mejor que tratar de manejar una escritura. Gracias por su ayuda!
  • No hay problema. Tengo la esperanza de que yo era capaz de ayudar.

InformationsquelleAutor T. Evans | 2017-08-14

7 Comentarios

  1. 16

    Me encontré con este mismo problema hoy en día cuando se trata de implementar un filtro /función de búsqueda en la nueva FlatList componente. Esto es cómo me las arreglé para resolver es:

    Mediante la creación de otro elemento en el estado del componente padre se llama noData, se puede establecer que a la verdad cuando no hay resultados que coincidan con su búsqueda y, a continuación, hacer que su FlatList condicionalmente.

    Mi aplicación es ligeramente diferente a la tuya, pero si he tenido que ajustar su código sería algo como esto:

    Buscartexto función:

    searchText = (e) => {
        let text = e.toLowerCase()
        let trucks = this.state.data
        let filteredName = trucks.filter((item) => {
          return item.name.toLowerCase().match(text)
        })
        if (!text || text === '') {
          this.setState({
            data: initial
          })
        } else if (!Array.isArray(filteredName) && !filteredName.length) {
          //set no data flag to true so as to render flatlist conditionally
          this.setState({
            noData: true
          })
        } else if (Array.isArray(filteredName)) {
          this.setState({
            noData: false,
            data: filteredName
          })
        }
      }

    A continuación, pasar el noData bool a su TruckList componente:

    <TruckList getTruck={(truck) => this.setTruck(truck)} 
    truckScreen={this.truckScreen} data={this.state.data} noData={this.state.noData}/>

    A continuación, hacer que su FlatList en el TruckList componente sólo si existen resultados:

    <List style={styles.list}>
    {this.props.noData ? <Text>NoData</Text> : <FlatList {...} />}         
    </List>

    Que luego debe encargarse de la gestión del usuario, errores de escritura – que se va a volver a renderizar el flatlist tan pronto como no hay ningún resultado, y recordará el anterior estado de la búsqueda cuando se quita el error de mecanografía..

    Hágamelo saber si eso ayuda!

    • ¿Ustedes tienen un enlace de github para esta solución ?
    • no trabajo para mí , cuando estoy haciendo la consola de camiones.filtro((elemento) => {console.registro(punto) } es dar «mensaje: «el elemento no está definida»»
    • en el punto.nombre.método tolowercase() está dando error así
    • Si la consola de registro de los datos que se están filtrando ¿recibe algún datos no?
    • Está pasando this.props.noData realmente necesario? ¿No sería más limpio solo para comprobar if(this.props.data)
  2. 9

    Actualización:
    Este blog puede ayudar a comprender mejor la búsqueda en un FlatList.

    FYI:
    Si usted tiene enorme de datos en línea, a continuación, también puede utilizar algolia.

    He ajustado el código de arriba para mí con el fin de que funcione correctamente. La razón es que cuando el usuario elimina el último carácter equivocado, la búsqueda de código de esta nueva cadena a partir de una búsqueda anterior lista (estado) que no contiene todos los objetos, aunque tuviera que buscar en una lista completa disponible. Así que, yo tengo dos de la lista ahora. Uno contiene la lista completa de los objetos y la segunda contiene solo se representan en la lista de objetos que está cambiando en la búsqueda.

    handleSearchInput(e){
        let text = e.toLowerCase()
        let fullList = this.state.fullListData;
        let filteredList = fullList.filter((item) => { //search from a full list, and not from a previous search results list
          if(item.guest.fullname.toLowerCase().match(text))
            return item;
        })
        if (!text || text === '') {
          this.setState({
            renderedListData: fullList,
            noData:false,
          })
        } else if (!filteredList.length) {
         //set no data flag to true so as to render flatlist conditionally
           this.setState({
             noData: true
           })
        }
        else if (Array.isArray(filteredList)) {
          this.setState({
            noData: false,
            renderedListData: filteredList
          })
        }
      }
  3. 4

    Para una útil en la memoria de la búsqueda que usted debería mantener datos iniciales por separado.

    Tengo más solución simple para esto.

    Esta solución en la memoria de la búsqueda en FlatList de datos y utiliza la Cadena.el prototipo.incluye (a) el método para la búsqueda de subcadenas.

    Usted puede encontrar el código fuente completo de este componente en este gist;
    https://gist.github.com/metehansenol/46d065b132dd8916159910d5e9586058

    Mi estado inicial;

    this.state = {
      searchText: "",
      data: [],
      filteredData: []
    };

    Mi barra de búsquedas componente (viene de reaccionar-nativo-elementos del paquete);

    <SearchBar
      round={true}
      lightTheme={true}
      placeholder="Search..."
      autoCapitalize='none'
      autoCorrect={false}
      onChangeText={this.search}
      value={this.state.searchText}
    />

    Mi método de búsqueda;

    search = (searchText) => {
      this.setState({searchText: searchText});
    
      let filteredData = this.state.data.filter(function (item) {
        return item.description.includes(searchText);
      });
    
      this.setState({filteredData: filteredData});
    };

    Y último de mi FlatList del origen de datos de expresión;

    <FlatList
      data={this.state.filteredData && this.state.filteredData.length > 0 ? this.state.filteredData : this.state.data}
      keyExtractor={(item) => `item-${item.id}`}
      renderItem={({item}) => <ListItem
        id={item.id}
        code={item.code}
        description={item.description}
      />}
    />

    Feliz codificación…

  4. 2

    Aquí está mi solución:

    Usted necesita tener una copia de seguridad de sus datos

    this.state = {
        data: [],
        backup: []
    }

    sobre el método de búsqueda

    search = txt => {
        let text = txt.toLowerCase()
        let tracks = this.state.backup
        let filterTracks = tracks.filter(item => {
        if(item.name.toLowerCase().match(text)) {
          return item
        }
      })
      this.setState({ data: filterTracks })
    }

    Explicación: cuando se llama a setState de los datos que se le ha cambiado el estado actual y no puede ser cambiado de nuevo.

    Modo de copia de seguridad de datos de la manija para filtrar los datos.

  5. 2

    ref – https://medium.freecodecamp.org/how-to-build-a-react-native-flatlist-with-realtime-searching-ability-81ad100f6699

    constructor(props) {
    super(props);
    this.state = {
      data: [],
      value: ""
    };
    
    this.arrayholder = [];
    }

    Siguiente obtención de datos :-

    _fetchdata = async () => {
    const response = await fetch("https://randomuser.me/api?results=10");
    const json = await response.json();
    this.setState({ data: json.results });
    
    this.arrayholder = json.results;
    };

    Próximo definir searchFilterFunction :-

    searchFilterFunction = text => {
    this.setState({
      value: text
    });
    
    
    const newData = this.arrayholder.filter(item => {
      const itemData = item.email.toLowerCase();
    
      const textData = text.toLowerCase();
    
      return itemData.indexOf(textData) > -1;
    });
    
    this.setState({ data: newData });
    };

    representación searchView:-

        <TextInput
          style={{ height: 40, borderColor: "gray", borderWidth: 1 }}
          onChangeText={text => this.searchFilterFunction(text)}
        />

    No te olvides de importación TextInput de «reaccionar-nativo»;

  6. 0

    FYI : data es el subtext a ser buscado, esto es una búsqueda básica implementado como los datos a ser registrados se veía en cada elemento de la lista de una matriz que es una copia de la real array/array de objects y, finalmente, su estado es establecer si se encuentra coincidencia o no entre 0 a (actualArray.length-1) y el temporal arrayData se representa si hay al menos un partido más actualArray se representa

    JS:

    implementSearch(data) {
        temp = [];
        var count = 0;
        var searchData = data.toUpperCase();
        var arr = this.state.personDetail;
        for (var i = 0; i < arr.length; i++) {
          var actualData = arr[i].name.toUpperCase();
          if (actualData.includes(searchData)) {
            temp.push(arr[i]);
            count++;
          }
        }
        this.setState({
          tempArray: temp,
          matches: count,
          searchValue: data
        });
      }

    Esperanza esto ayuda a

  7. 0

    Mi método de búsqueda; de @metehan-senol

    search = (searchText) => {
      this.setState({searchText: searchText});
    
      let filteredData = this.state.data.filter(function (item) {
        return item.description.includes(searchText);
      });
    
      this.setState({filteredData: filteredData});
    };

    el método de búsqueda de la se podría simplificar y Eslint prueba como

    search = (searchText) => {
      const searched = searchText.toLowerCase();
      this.setState(prevState => ({
        searchText: searched,
        filteredData: prevState.data.filter(item =>
          item.description.toLowerCase().includes(searched)
        ),
      }));
    }; 

Dejar respuesta

Please enter your comment!
Please enter your name here