Rumah >hujung hadapan web >tutorial js >Membina Aplikasi Luar Talian yang diutamakan dengan React Native
Bayangkan apl anda digunakan oleh peruncit yang mengemas kini tahap stok, wakil jualan yang mengakses data pelanggan atau mana-mana pengguna menghantar mesej semasa sambungan terputus-putus. Dalam semua kes ini, kefungsian luar talian boleh bermakna perbezaan antara pengalaman pengguna yang lancar dan pengalaman pengguna yang mengecewakan. Di sinilah pemikiran luar talian yang mengutamakan dimainkan.
Pendekatan Luar Talian yang mengutamakan memastikan apl anda kekal berfungsi walaupun semasa Internet tidak tersedia. Aplikasi seperti WhatsApp menggambarkan konsep ini dengan sempurna. Apabila anda menghantar mesej semasa di luar talian, mesej itu disimpan secara setempat dan dihantar secara automatik sebaik sahaja sambungan dipulihkan. Pengalaman lancar ini dicapai dengan memanfaatkan storan tempatan dan memantau status rangkaian. Sama ada melalui pangkalan data atau memori peranti, apl itu terus berfungsi, menyegerakkan data yang disimpan dengan pelayan apabila sambungan tersedia semula.
Dalam artikel ini, saya akan membimbing anda melalui pelaksanaan sokongan luar talian dalam aplikasi React Native menggunakan storan setempat, penyegerakan pangkalan data dan API Ekspo. Faedah pendekatan Luar Talian yang diutamakan termasuk:
Ekspo ialah rangka kerja yang bagus untuk pembangunan React Native kerana ia mengabstraksi banyak konfigurasi khusus platform, membolehkan anda menumpukan pada ciri membina. Dalam bahagian ini, kami akan meneroka cara melaksanakan sokongan luar talian dalam apl React Native yang mudah menggunakan Expo, AsyncStorage untuk storan setempat dan NetInfo untuk pengesanan status rangkaian.
Mula-mula, mari mulakan dengan mencipta projek React Native dikuasakan Ekspo baharu.
npx create-expo-app offline-first-app cd offline-first-app
Untuk contoh ini, kami akan menggunakan dua perpustakaan utama:
@react-native-async-storage/async-storage: Pustaka ini akan membenarkan kami menyimpan data pada peranti.
@react-native-community/netinfo: Pustaka ini akan membantu kami mengesan status rangkaian, menentukan sama ada peranti dalam talian atau luar talian.
Pasang pakej yang diperlukan:
expo install @react-native-async-storage/async-storage @react-native-community/netinfo
Seterusnya, kami akan membina aplikasi mudah yang mengambil data daripada API semasa dalam talian dan menyimpannya secara setempat untuk digunakan semasa di luar talian. Kami akan bermula dengan menyediakan struktur asas dalam App.js:
import React, { useState, useEffect } from 'react'; import { StyleSheet, Text, View, Button, FlatList } from 'react-native'; import AsyncStorage from '@react-native-async-storage/async-storage'; import NetInfo from '@react-native-community/netinfo'; const DATA_API = 'https://jsonplaceholder.typicode.com/posts'; export default function App() { const [data, setData] = useState([]); const [isOffline, setIsOffline] = useState(false); useEffect(() => { const loadData = async () => { // Check network status const netInfo = await NetInfo.fetch(); setIsOffline(!netInfo.isConnected); if (netInfo.isConnected) { // Fetch data from API when online try { const response = await fetch(DATA_API); const result = await response.json(); setData(result); // Cache the data for offline use await AsyncStorage.setItem('cachedData', JSON.stringify(result)); } catch (error) { console.error('Failed to fetch data:', error); } } else { // Load data from AsyncStorage when offline try { const cachedData = await AsyncStorage.getItem('cachedData'); if (cachedData) { setData(JSON.parse(cachedData)); } } catch (error) { console.error('Failed to load data from cache:', error); } } }; loadData(); }, []); return ( <View style={styles.container}> <Text style={styles.header}>Offline-First App</Text> <Text>Status: {isOffline ? 'Offline' : 'Online'}</Text> <FlatList data={data} keyExtractor={(item) => item.id.toString()} renderItem={({ item }) => ( <View style={styles.item}> <Text style={styles.title}>{item.title}</Text> </View> )} /> <Button title="Reload" onPress={() => loadData()} /> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, paddingTop: 50, paddingHorizontal: 20, backgroundColor: '#fff', }, header: { fontSize: 24, fontWeight: 'bold', marginBottom: 20, }, item: { backgroundColor: '#f9c2ff', padding: 20, marginVertical: 8, }, title: { fontSize: 16, }, });
Bagaimana Ia Berfungsi?
Pengesanan Status Rangkaian: Menggunakan pustaka NetInfo, kami menyemak sama ada peranti itu dalam talian atau luar talian. Jika dalam talian, apl itu mengambil data daripada API dan menyimpannya dalam cache. Jika peranti di luar talian, apl itu mendapatkan semula data cache daripada AsyncStorage.
Caching Data: AsyncStorage membenarkan kami menyimpan data yang diambil daripada API untuk akses luar talian. Ini penting untuk menjadikan apl berfungsi tanpa sambungan internet yang aktif.
Penyegerakan Data: Apabila ketersambungan dipulihkan, apl mengambil data baharu daripada API dan mengemas kini cache, memastikan pengguna sentiasa mendapat maklumat terkini apabila mereka berada dalam talian.
Anda boleh membina kefungsian asas ini dengan menyepadukan ciri yang lebih maju, seperti:
Strategi Penyegerakan: Sesetengah apl memerlukan strategi penyegerakan lanjutan, di mana konflik mungkin timbul (mis., dua pengguna mengemas kini data yang sama di luar talian). Alat seperti PouchDB atau Firebase boleh membantu mengurus penyegerakan data masa nyata dan penyelesaian konflik.
Penyelesaian Pangkalan Data: Untuk apl yang lebih kompleks, anda mungkin mahu menggunakan pangkalan data setempat seperti Realm atau SQLite untuk mengendalikan set data yang lebih besar dan pertanyaan yang lebih canggih.
Kemas Kini Optimis: Dalam sesetengah apl, terutamanya yang mempunyai kandungan jana pengguna seperti media sosial, adalah perkara biasa untuk membenarkan pengguna membuat, mengemas kini atau memadam data di luar talian. Anda boleh melaksanakan kemas kini optimistik, di mana perubahan dibuat dalam UI serta-merta dan disegerakkan dengan pelayan apabila apl disambungkan semula ke Internet.
In an offline-first app, conflicts arise when multiple users update the same data while offline and their changes are later synced with the server once the app reconnects to the internet. Handling these conflicts is crucial to maintain data consistency and provide a smooth user experience.
There are different strategies for resolving such conflicts, including:
I have some examples here for you to check.
In this strategy, the most recent change (based on a timestamp) is accepted as the final value when syncing data. It is simple and works well for many applications, but it may lead to data loss if multiple users edit the same data.
Imagine you are building a note-taking app, if two users edit the same note while offline, the user who syncs their changes last will overwrite the previous user’s changes.
Let’s assume we have a local storage system (using AsyncStorage) and a remote server.
import AsyncStorage from '@react-native-async-storage/async-storage'; // Simulate syncing the note data with the server const syncNoteWithServer = async (localNote) => { try { // Fetch the server data const response = await fetch('https://api.example.com/note'); const serverNote = await response.json(); // Compare timestamps if (localNote.updatedAt > serverNote.updatedAt) { // Local version is newer, so overwrite the server await fetch('https://api.example.com/note', { method: 'PUT', body: JSON.stringify(localNote), headers: { 'Content-Type': 'application/json' }, }); } else { // Server version is newer, discard local changes await AsyncStorage.setItem('note', JSON.stringify(serverNote)); } } catch (error) { console.error('Sync failed:', error); } }; // Example usage const localNote = { content: 'This is an updated note.', updatedAt: Date.now(), // Timestamp of the last local update }; syncNoteWithServer(localNote);
In this example:
The app compares the updatedAt timestamp of the local note (stored offline) with the note stored on the server.
If the local note is newer, it overwrites the server version. Otherwise, it discards local changes and updates the app with the server version.
Pros:
Cons:
With manual conflict resolution, the user is prompted to resolve conflicts when multiple versions of the same data exist. This approach is more user-friendly in scenarios where every change is valuable and users need to decide which data to keep.
Here is a potential case: In a collaborative editing app, two users edit the same document while offline. Once both versions are synced, the user is prompted to choose which version to keep or merge.
import AsyncStorage from '@react-native-async-storage/async-storage'; import { Alert } from 'react-native'; // Simulate syncing the document with the server const syncDocumentWithServer = async (localDoc) => { try { // Fetch the server data const response = await fetch('https://api.example.com/document'); const serverDoc = await response.json(); if (localDoc.updatedAt !== serverDoc.updatedAt) { // Conflict detected, ask the user to resolve it Alert.alert( 'Document Conflict', 'Both you and another user have edited this document. Choose which version to keep.', [ { text: 'Keep Local', onPress: async () => { // Overwrite the server with local changes await fetch('https://api.example.com/document', { method: 'PUT', body: JSON.stringify(localDoc), headers: { 'Content-Type': 'application/json' }, }); }, }, { text: 'Keep Server', onPress: async () => { // Discard local changes and update the app with the server version await AsyncStorage.setItem('document', JSON.stringify(serverDoc)); }, }, ], ); } else { // No conflict, proceed with syncing await AsyncStorage.setItem('document', JSON.stringify(serverDoc)); } } catch (error) { console.error('Sync failed:', error); } }; // Example usage const localDoc = { content: 'This is my latest edit.', updatedAt: Date.now(), // Timestamp of the last local update }; syncDocumentWithServer(localDoc);
Here's what's happening
If the updatedAt timestamps differ between the local and server versions, the app alerts the user and asks them to choose which version to keep. The user can decide whether to keep the local or server version.
Pros:
Cons:
3. Operational Transformation (OT)
Operational Transformation is a more advanced technique used in real-time collaboration apps like Google Docs. It automatically merges conflicting changes by transforming operations in a way that preserves both sets of edits. OT allows multiple users to work on the same document simultaneously, and their changes are merged intelligently.
In a document editor app, two users edit different parts of a document. OT ensures that both sets of edits are applied without overwriting each other.
This implementation is a bit complex and require specialized libraries, such as ShareDB or Yjs. Here’s a basic pseudocode example of how OT works:
// Example of transforming two concurrent operations const operation1 = { type: 'insert', position: 5, value: 'Hello' }; // User 1 adds 'Hello' at position 5 const operation2 = { type: 'insert', position: 3, value: 'World' }; // User 2 adds 'World' at position 3 const transformOperations = (op1, op2) => { // If both operations modify different positions, no conflict if (op1.position !== op2.position) return [op1, op2]; // If operations conflict, adjust positions accordingly if (op1.position > op2.position) op1.position += op2.value.length; else op2.position += op1.value.length; return [op1, op2]; }; // Transform the operations to avoid conflicts const [transformedOp1, transformedOp2] = transformOperations(operation1, operation2);
The positions of the two conflicting operations are adjusted so that they can both be applied without overwriting each other.
Pros:
Cons:
Conclusion
Each conflict resolution strategy comes with its trade-offs. For simpler apps, Last Write Wins may suffice. However, for collaborative apps where user data is crucial, Manual Conflict Resolution or more advanced techniques like Operational Transformation might be necessary. Choosing the right strategy depends on the complexity of your app and the importance of the data being modified.
I plan to create a series of articles that dive deeper into the following key topics:
Optimistic UI Updates – We'll explore how to immediately reflect changes made while offline in the UI, giving users the impression that their actions were successful. This approach greatly improves the user experience.
Menggunakan Service Workers untuk Apl Berasaskan Web – Jika anda menggunakan apl anda di web melalui React Native Web, saya akan menerangkan cara pekerja perkhidmatan boleh mendayakan cache luar talian dan penyegerakan latar belakang untuk Progressive Web Apl (PWA). Ini memastikan pengguna boleh mengakses sumber dan data walaupun mereka berada di luar talian.
Kes Penggunaan Dunia Sebenar Apl Luar Talian Diutamakan – Saya akan melihat dengan lebih dekat cara apl seperti Peta Google, Slack, Trello dan Notion mengendalikan senario luar talian. Dengan mempelajari contoh ini, anda akan mendapat pemahaman yang lebih baik tentang aplikasi praktikal teknik luar talian yang diutamakan.
Menguji Keupayaan Luar Talian – Kami akan merangkumi kepentingan menguji kefungsian luar talian dan alat semakan seperti React Native Debugger, alatan Ekspo dan Perapi Pautan Rangkaian (untuk iOS) untuk mensimulasikan gangguan rangkaian. Saya juga akan menunjukkan kepada anda cara menulis ujian menggunakan perpustakaan seperti Jest dan React Native Testing Library untuk memastikan apl anda berfungsi dengan betul dalam keadaan luar talian.
Pertimbangan Prestasi dan Storan – Prestasi bukan hanya tentang kelajuan; ia juga mengenai pengalaman pengguna. Saya akan membincangkan strategi untuk mengoptimumkan prestasi dengan mengurangkan data yang dicache dan melaksanakan dasar tamat tempoh data untuk mengelakkan storan setempat yang melampau.
Nantikan devs.
Terima kasih kerana membaca sehingga habis. Saya benar-benar suka mendokumentasikan dan berkongsi pembelajaran saya. Saya merancang untuk mencipta lebih banyak kandungan, termasuk tutorial video, yang akan saya kongsikan di Instagram dan TikTok. Jika anda baru di sini, saya Zidane Gimiga, pembangun perisian dengan semangat untuk mengoptimumkan pengalaman pengguna. Apabila teknologi menjadi lebih bersepadu ke dalam kehidupan kita, adalah penting untuk menjadikannya semudah dan boleh diakses sebaik mungkin untuk semua orang. Mari teruskan usaha untuk mendapatkan penyelesaian yang lebih baik dan mesra pengguna.
Oh, saya menggunakan Github
Atas ialah kandungan terperinci Membina Aplikasi Luar Talian yang diutamakan dengan React Native. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!