Tengo una aplicación simple que se conecta a una base de datos sqlite, lee los resultados de esa base de datos y los muestra. Aquí está la aplicación:
import React, { useEffect, useState } from 'react'; import { View, Text } from 'react-native' import * as SQLite from "expo-sqlite"; import * as FileSystem from 'expo-file-system'; import { Asset } from 'expo-asset'; async function openDatabase() { if (!(await FileSystem.getInfoAsync(FileSystem.documentDirectory + 'SQLite')).exists) { await FileSystem.makeDirectoryAsync(FileSystem.documentDirectory + 'SQLite'); } await FileSystem.downloadAsync( Asset.fromModule(require('./assets/banana-dict.db')).uri, FileSystem.documentDirectory + 'SQLite/banana-dict.db' ); return SQLite.openDatabase('banana-dict.db'); } export default function App() { const [ dicts, setDicts ] = useState([]); const [ db, setDb ] = useState({ transaction: () => { return { executeSql: () => {}, }; }}); const updateDicts = (a) => { setDicts( Object.fromEntries(a.map(({rowid, ...rest}) => [rowid, rest])) ); } const fetchDicts = () => { console.log('fetch') db.transaction((tx) => { tx.executeSql( `select rowid, * from dicts;`, [], (_, { rows: { _array } }) => { console.log(_array); updateDicts(_array); } ); }); } useEffect(() => { openDatabase().then((value) => { setDb(value); fetchDicts(); }); }, []); return ( <View style={{marginTop: 100}}> <Text>Open App.js to start working on your app!</Text> <Text>{JSON.stringify(dicts)}</Text> </View> ); } banana-dict.db es una base de datos preexistente que estoy usando para esta aplicación. Descubrí que si inicio la aplicación y la abro en mi teléfono, el estado de los dicts (es decir, los resultados de una consulta en la base de datos) no aparece. Sin embargo, si presiono r en la consola para actualizar, los resultados aparecen de inmediato. ¿Alguien sabe por qué es esto?
Cuando se inicia la aplicación, se establece el valor de db inicial. El primer efecto procesa por lotes setDb y fetchDicts , por lo que db.transaction no se ha actualizado con el valor de la llamada a setDb . Debido a que Expo tiene una actualización con estado, la base de datos ya no se establece como el valor inicial sino que tiene el resultado de db , setDb lo que fetchDicts funciona y aparecen los resultados.
Una forma de solucionar esto sería mover fetchDicts a su propio efecto y llamarlo cuando db la base de datos.
useEffect(() => { openDatabase().then((value) => { setDb(value); }); }, []); useEffect(() => { fetchDicts(); // will do nothing until db connection is open }, [db]);