Search code examples
react-nativereact-hookshookreact-native-flatlistsearchbar

Adding Search Bar into Flatlist using Hook, Undefined


i try to create flatlist inside modal with search bar functionality that can filter the result based on user input in the search bar.

For the flatlist everything show up accordingly, problem i can't filter the data, i try using .filter from the original full data (list) but result is always undefined is not a data.

Btw data is populate from local .json file to state using useEffect.

Here is the local country.json data :

[
"Japan", 
"Korea", 
"Thailand", 
"Indonesia" ]

Here is part of the source code :

import dataCountry from '../../assets/json/country.json';

const NameScreen = ({ navigation }) => {

// hook
const [list, setList] = useState([]);
const [modalBirthplace, setModalBirthplace] = useState(false);
const [searchText, setSearchText] = useState('');

useEffect(() => {
    setList({ dataCountry });
    console.log('check List : ', list);
}, [])

const renderItem = ({ item }) => (
    <Item title={item.title} />
);

const ListItem = ({ title }) => (
    <View>
        <TouchableOpacity onPress={() => console.log("ok")}>
            <Text style={styles.cityList}>{title}</Text>
        </TouchableOpacity>
    </View>
);

const searchFilterFunction = searchText => {

    setSearchText(searchText);
    console.log(searchText)

    const newData = list.filter((item) => { // error trigger from this list.filter undefined is not a function
        const itemData = item.toUpperCase();
        const textData = searchText.toUpperCase();
        return itemData.indexOf(textData) > -1;
      });

    setList(newData);
};

return (
    <View style={styles.container}>
        <Modal
            animationType="slide"
            transparent={true}
            visible={modalBirthplace}
            onRequestClose={() => {
                Alert.alert('Modal has been closed.');
            }}>
            <View style={styles.centeredView}>
                <View style={styles.modalView}>
                    <Text style={styles.modalText}>Choose your country location :</Text>
                    <TextInput
                        placeholder="Try japan maybe?"
                        onChangeText={searchText => searchFilterFunction(searchText)}
                        value={searchText}
                    />
                    <FlatList
                        data={list.dataCountry}
                        renderItem={({ item }) => (
                            <ListItem
                                title={item}
                            />
                        )}
                        keyExtractor={item => item}
                    />
                    <TouchableHighlight
                        style={{ ...styles.openButton, backgroundColor: '#E15C72' }}
                        onPress={() => {
                            setModalBirthplace(!modalBirthplace);
                        }}>
                        <Text style={styles.textStyle}>Close Selection</Text>
                    </TouchableHighlight>
                </View>
            </View>
        </Modal>
    </View>
)

}

Anybody know why i can't filter the state?

Thanks a lot before


Solution

  • the problem is your state is an JSON object, not an array:

    setList({ dataCountry });
    // so list is: 
    {
      dataCountry: [
        ...
      ]
    }
    

    so, you need to change here

    const newData = list.dataCountry.filter((item) => { // here
            const itemData = item.toUpperCase();
            const textData = searchText.toUpperCase();
            return itemData.indexOf(textData) > -1;
          });
    
        setList({dataCountry: newData}); // and here