React Native 应用程序的 expo-sqlite 回调直到应用程序刷新才执行
React Native app's expo-sqlite callback not executed until app refresh
我有一个简单的应用程序,可以连接到 sqlite 数据库,从该数据库读取结果并显示它们。这是应用程序:
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
是我用于此应用程序的预先存在的数据库。
我发现如果我启动应用程序并在我的 phone 上打开它,dicts
状态(即数据库查询的结果)不会出现。但是,如果我在控制台中按 r
进行刷新,结果会立即出现。
有人知道这是为什么吗?
当应用程序启动时,会设置初始 db
值。第一个效果批处理 setDb
和 fetchDicts
,因此 db.transaction
尚未更新为 setDb
调用的值。因为 Expo 有状态刷新,所以 db
不再设置为初始值,而是有 setDb
的结果,所以 fetchDicts
工作,结果出现。
解决此问题的一种方法是将 fetchDicts
移动到它自己的效果中,并在 db
更改时调用它。
useEffect(() => {
openDatabase().then((value) => {
setDb(value);
});
}, []);
useEffect(() => {
fetchDicts(); // will do nothing until db connection is open
}, [db]);
我有一个简单的应用程序,可以连接到 sqlite 数据库,从该数据库读取结果并显示它们。这是应用程序:
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
是我用于此应用程序的预先存在的数据库。
我发现如果我启动应用程序并在我的 phone 上打开它,dicts
状态(即数据库查询的结果)不会出现。但是,如果我在控制台中按 r
进行刷新,结果会立即出现。
有人知道这是为什么吗?
当应用程序启动时,会设置初始 db
值。第一个效果批处理 setDb
和 fetchDicts
,因此 db.transaction
尚未更新为 setDb
调用的值。因为 Expo 有状态刷新,所以 db
不再设置为初始值,而是有 setDb
的结果,所以 fetchDicts
工作,结果出现。
解决此问题的一种方法是将 fetchDicts
移动到它自己的效果中,并在 db
更改时调用它。
useEffect(() => {
openDatabase().then((value) => {
setDb(value);
});
}, []);
useEffect(() => {
fetchDicts(); // will do nothing until db connection is open
}, [db]);