Home > other >  Problem filtering and rendering an array asynchronously in React native
Problem filtering and rendering an array asynchronously in React native

Time:11-27

I'm trying to apply a filter in one array of objects with the property Id to get the list of items that starts with the text from an input. I have only two elements in the array but if I ever get the same two elements (render as a list).

What i need to do for fix the filter logic in function SearchFilter?

import React, { useEffect, useState } from "react"
import {useSelector} from 'react-redux'
import {View, Item, Text, Icon, Input, List, ListItem, Left, Thumbnail, Spinner} from 'native-base'

const SearchModal =(props:any)=>{
  const sessionsCata = useSelector((state)=> state.sessionsCata.sessions)
  const [itemsFiltered, setItemsFiltered] = useState([]) 
  const [showSpinner, setShowSpinner] =useState(false)

  //filter the array objects
  async function SearchFilter(params:string) {
    setShowSpinner(true)
    if(sessionsCata && sessionsCata.length>0){
        let result = await sessionsCata.filter(async x=> x.Id.startsWith(params) )
        if(result)
            setItemsFiltered(result)
    }            
    await Sleep(500) //function with Promise-setTimeout
    setShowSpinner(false)
  }

  return(
        <View style={StylesSearch.containerBar} >
            <Item rounded style={StylesSearch.searchBar}>
                <Input placeholder='Id...' onChangeText={async (text) => await SearchFilter(text)} />
            </Item>
        </View>
        <View> 
            { showSpinner ? <Spinner color='grey'/> :
                itemsFiltered && itemsFiltered.length>0 ? (
                    <List>
                    {
                        itemsFiltered.map(item=>(
                            <ListItem avatar key={item.id}>
                                <Body>
                                    <Text>{item.id}</Text>
                                </Body>
                            </ListItem>
                        ))
                    }                      
                    </List> 
                ): <Text>Not items filtered...</Text>
            }                                   
            </View>
   )
}

CodePudding user response:

You don't need to use async/await on the filter. It's not async. Also, since itemsFiltered is deterministic (based on sessionsCata state), it shouldn't be its own state.

const [prefix, setPrefix] = useState("");

const itemsFiltered = sessionsCata.filter(x => x.Id.startsWith(prefix));

// Then
<Input onChangeText={setPrefix} />

CodePudding user response:

Change :

if(sessionsCata && sessionsCata.length>0){
    let result = await sessionsCata.filter(async x=> x.Id.startsWith(params) )
    if(result)
    {
      if(JSON.stringify(itemsFiltered).includes(JSON.stringify(result)))
      return;
      setItemsFiltered(result)
    }        
} 
  • Related