我正在開發一個帶有 React Native 和 Expo 托管作業流的移動應用程式。該應用程式應該用作帶有歌曲和贊美詩歌詞的歌本。所有歌詞都存盤在 Firebase 的 Firestore 資料庫中,客戶端可以將它們加載到應用程式中。我開始實作離線功能,所有歌詞都使用社區的AsyncStorage存盤在用戶的設備上。
我想首先獲取存盤在 AsyncStorage 中的資料,將它們設定為保存歌曲的狀態變數,然后查看用戶是否可以訪問互聯網。如果是,我想檢查 Firestore 中的更新,如果有,我會將 Firestore 中的資料設定為保存歌曲的狀態變數。如果用戶沒有 Internet 訪問權限,則來自 AsyncStorage 的資料將已設定為保存歌曲的狀態變數。
我正在嘗試使用 useEffect 鉤子中的異步函式來實作這一點,其中包含空的 vars/dependecies 陣列。我遇到的問題是,即使從 AsyncStorage 成功檢索到歌曲,也不會在螢屏上呈現歌曲。
(當我控制臺記錄從 AsyncStorage 檢索資料的輸出時,我可以看到所有歌曲,當我控制臺日志歌曲或 allSongs 狀態變數時,我變得未定義)
這是我的簡化代碼:
import React, { useEffect, useState } from 'react';
import {
StyleSheet,
FlatList,
SafeAreaView,
LogBox,
View,
Text,
} from 'react-native';
import { StatusBar } from 'expo-status-bar';
import { filter, _ } from 'lodash';
import { doc, getDoc } from 'firebase/firestore';
import NetInfo from '@react-native-community/netinfo';
import { db } from '../../../firebase-config';
import { ThemeContext } from '../../util/ThemeManager';
import {
getStoredData,
getStoredObjectData,
storeData,
storeObjectData,
} from '../../util/LocalStorage';
const SongsList = ({ route, navigation }) => {
// const allSongs = props.route.params.data;
const { theme } = React.useContext(ThemeContext);
const [loading, setLoading] = useState(false);
const [allSongs, setAllSongs] = useState();
const [songs, setSongs] = useState(allSongs);
const hymnsRef = doc(db, 'index/hymns');
useEffect(() => {
const setup = async () => {
setLoading(true);
const locData = await getStoredObjectData('hymnsData');
console.log(locData);
setAllSongs(locData);
setSongs(locData);
const netInfo = await NetInfo.fetch();
if (netInfo.isInternetReachable) {
const data = await getDoc(hymnsRef);
const lastChangeDb = data.get('lastChange').valueOf();
const hymnsData = data.get('all');
const lastChangeLocal = await getStoredData('lastChange');
if (lastChangeLocal) {
if (lastChangeLocal !== lastChangeDb) {
await storeData('lastChange', lastChangeDb);
await storeObjectData('hymnsData', hymnsData);
setAllSongs(hymnsData);
setSongs(hymnsData);
}
}
}
sortHymns();
setLoading(false);
};
setup();
}, []);
return (
<SafeAreaView style={[styles.container, styles[`container${theme}`]]}>
{!loading ? (
<FlatList
data={songs}
keyExtractor={(item) => item?.number}
renderItem={({ item }) => {
return <ListItem item={item} onPress={() => goToSong(item)} />;
}}
ItemSeparatorComponent={Separator}
ListHeaderComponent={
route.params.filters ? (
<SearchFilterBar
filters={filters}
handleFilter={handleFilter}
query={query}
handleSearch={handleSearch}
seasonQuery={seasonQuery}
setSeasonQuery={setSeasonQuery}
/>
) : (
<SearchBar handleSearch={handleSearch} query={query} />
)
}
/>
) : (
<View>
<Text>loading</Text>
</View>
)}
<StatusBar style={theme === 'dark' ? 'light' : 'dark'} />
</SafeAreaView>
);
};
export default SongsList;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
getStoredData、getStoredObjectData、storeData 和 storeObjectData 函式只是 AsyncStorage 的 getItem 和 setItem 方法。
這是我的完整代碼 - GitHub。
我究竟做錯了什么?我已經閱讀了許多教程和文章,它應該可以作業......但我猜不是?
uj5u.com熱心網友回復:
你可以檢查是否hymnsData未定義?線后const hymnsData = data.get('all');。
如果是這樣,那將解釋問題 - 您正確設定locData但隨后立即覆寫它。如果是這種情況,我會將 hymnsData 添加到 if 條件if (hymnsData && lastChangeLocal) { ... }
如果您在 之前記錄歌曲和 allSongs return (,您是否看到它們已被填充,簡短地說?
我要除錯的另一件事是注釋掉
setAllSongs(hymnsData);
setSongs(hymnsData);
行并查看它是否僅與 locData 一起按預期作業
uj5u.com熱心網友回復:
問題出在 sortHymns() 方法上。我將它從它自己的方法移到 useEffect 并且它現在正在作業。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/456697.html
