State variable defined by useState is not working in react native

142 Views Asked by At

Can someone please findout what is wrong in this code? Getting nothing from the flatlist. The state variable items is also showing null.

import React, { useEffect, useState } from 'react';
import { FlatList, SafeAreaView, TextInput, Text, Button, Alert } from 'react-native';
import { openDatabase } from 'react-native-sqlite-storage';

const db = openDatabase({name: 'sqlitedb3 '});

const App = () => {

  const [text, setText] = useState('');
  const [items, setItems] = useState([]);

  async function init() {
    await handleInit();
    await handleFetch();
  }

  useEffect(() => {
    init();
  }, [])

  const handleInit = async() => {
    await db.transaction((txn) => {
      txn.executeSql('CREATE TABLE IF NOT EXISTS Items ('+
        'id INTEGER PRIMARY KEY AUTOINCREMENT,'+
        'item VARCHAR(30))', [], (tx, res) => {
        console.log('table created');
      })
    })
  }

  const handleFetch = async() => {
    await db.transaction((txn) => {
      txn.executeSql('SELECT * FROM Items', [], (tx, res) => {
        let n = res.rows.length;
        console.log('fetched '+n+' items');
        let result = [];
        for(let i = 0; i < n; i++) {
          result.push({id: res.rows.item(i).id, item: res.rows.item(i).item });
          console.log(res.rows.item(i).id+". "+res.rows.item(i).item)
        }
        setItems(result);
        console.log('state.items: '+items.length)
      })
    })
  }

  const handleSubmit = async() => {
    console.log('submit pressed');
    if(text === null || text === '') {
      Alert.alert('text input is blank');
      return;
    }
    
    try {
      await db.transaction((txn) => {
        txn.executeSql('INSERT INTO Items (item) VALUES (?)', [text],async (tx, res) => {
          console.log('saved successfully');
          setText('');
          await handleFetch();
        })
      })
    }
    catch(err) {
      console.log("can't submit")
    }
  }

  const renderlist = ({val}) => {
    return(<Text>{val.item}</Text>)
    
  }

  return(
    <SafeAreaView>
      <TextInput 
        value={text} 
        onChangeText={(val)=>setText(val)} />
      <Button
        onPress={() => { handleSubmit() }}
        title='Submit'/>
      <Text>Hello</Text>
      <FlatList 
        data={items} 
        renderItem={renderlist}
      />
    </SafeAreaView>
  )
}

export default App;

console output:

LOG table created

LOG table created

LOG submit pressed

LOG saved successfully

LOG fetched 9 items

LOG 1. Heyy

LOG 2. m Gnutella fits n me gobo dl

LOG 3. Fnch h gcc

LOG 4. Geysgdsfsgd

LOG 5. Dyrydydyd

LOG 6. Vjvjvj

LOG 7. Xbxbx

LOG 8. Gdgx

LOG 9. Xvxdh

ERROR TypeError: undefined is not an object (evaluating 'val.item')

2

There are 2 best solutions below

1
Hen Moshe On

you need to change your FlatList& renderlist a bit, dont forget uppercases. try this instead :

 const RenderList = ({val}) => {
    return(<Text>{val.item}</Text>)
    
  }
<FlatList 
        data={items} 
        renderItem={({ item }) => (
        <RenderList val={item}
        />
      )}/>
1
Nicholas Mberev On

Try something like this:

useEffect(() => {
    if(!items.length){
     init();
    }
  }, [items]);