Flama
Flama

Reputation: 868

SearchBar from react-native-elements with FlatList only allows me to type characters one by one

I'm using SearchBar from react-native-elements in my application inside a functional component. However there's one issue I'm unable to fix: I can only type characters one by one. I cannot continuously write my text inside my bar and then search. Instead I must type every character ony by one to find a specific word.

Here's my code:

export default function InstitutionsScreen({navigation}) {

  const [institutions, setInstitutions] = useState('');
  const [refresh, setRefresh] = useState(false);
  const [fullData, setFullData] = useState([]);
  const [value, setValue] = useState('');

  useEffect(() => {
    if(!institutions) {
      setRefresh(false);
      getInstitutions();
    }
  }, []);

  const contains = (institutionName, query) => {
    if (institutionName.includes(query)) {
      return true
    }
    return false
  }

  const handleSearch = text => {
    setValue(text);
    const formattedQuery = text.toLowerCase()
    console.log("flaco me diste " + formattedQuery)
    const data = filter(fullData, inst => {
      return contains(inst.name.toLowerCase(), formattedQuery)
    })
    setInstitutions(data);
  }

  const onRefresh = () => {
    setRefresh(true);
    getInstitutions();
  };

  const renderHeader = () => (
    <View
      >
        <SearchBar
        lightTheme
        clearIcon
        onChangeText={(text) => handleSearch(text)}
        value={value}
        placeholder='Buscar...' />
    </View>
  )

  if (!institutions || refresh) {
    return (
      <ScrollView contentContainerStyle={{alignItems: "center", flex: 1, justifyContent: 'center'}}>
        <Spinner isVisible={true} size={100} type={'Pulse'} color={'#013773'}/>
      </ScrollView>
    );
  } else {
    return (
      <View>
      <SafeAreaView>
        <FlatList
          data={institutions}
          renderItem={({ item }) => 
            <InstitutionItem 
              title={item.name} 
              image={require('../../../assets/hands.jpg')} 
              logo={require('../../../assets/institution.png')}
              location={item.address}
              phone={item.phone}
              email={item.email}
              navigation={navigation}
              id={item._id}
              />}
            keyExtractor={(item, index) => index.toString()}
            refreshing={refresh}
            onRefresh={() => onRefresh()}
            ListHeaderComponent={renderHeader}
        />
      </SafeAreaView>
      </View>
    );
  }
}

Upvotes: 0

Views: 726

Answers (1)

Tom
Tom

Reputation: 338

I tried your code, and it doesn't seem to be something related with the SearchBar, it works as it should outside of the FlatList. The problem that you are having is that you are losing the input focus for some reason on how you are "injecting" the SearchBar into the FlatList. So what I did, was to put the SearchBar right into the code, like this:

<FlatList
  data={institutions}
  keyExtractor={(item, index) => index.toString()}
  refreshing={refresh}
  onRefresh={() => onRefresh()}
  ListHeaderComponent={
    <SearchBar
    lightTheme
    clearIcon
    onChangeText={handleSearch}
    value={value}
    placeholder='Buscar...' />
  }
/>

and it worked, you are now able to keep writing without losing the focus. This is not a bad solution, it's an easy solution, but if this is not very to your liking, you should try to find how you can insert any component in the header of the FlatList from a function or a const. Abrazo!

Upvotes: 1

Related Questions