React Native待办应用实现安卓端本地持久化存储待办项的问题咨询
实现本地持久化的解决方案
你可以通过社区维护的AsyncStorage库实现安卓本地数据持久化,它是React Native官方推荐的轻量级键值存储方案,数据会保存在应用的私有沙盒目录,卸载应用前不会丢失。
实现步骤
第一步:安装依赖
执行安装命令:npm install @react-native-async-storage/async-storage安卓端不需要额外配置,直接可以使用。
第二步:修改现有代码
你需要新增数据读写逻辑,在应用启动时读取本地存储的任务列表,在任务新增/删除时同步更新本地存储,修改后的完整代码如下:import React, { useState, useEffect } from "react"; import { KeyboardAvoidingView, Platform, StyleSheet, Text, TextInput, Keyboard, TouchableOpacity, View, } from "react-native"; import AsyncStorage from '@react-native-async-storage/async-storage'; import Modal from "react-native-modal"; import Task from "./components/Task"; import { faTrophy } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-native-fontawesome"; // 存储key,避免拼写错误 const STORAGE_KEY = '@task_list'; export default function App() { const [task, setTask] = useState(); const [taskItems, setTaskItems] = useState([]); const [modalVisable, setModalVisable] = useState(false); const [itemToDelete, setItemToDelete] = useState(); // 读取本地存储的任务列表 const loadTasks = async () => { try { const savedTasks = await AsyncStorage.getItem(STORAGE_KEY); if (savedTasks !== null) { setTaskItems(JSON.parse(savedTasks)); } } catch (e) { console.error('读取任务失败', e); } }; // 保存任务列表到本地 const saveTasks = async (tasks) => { try { const jsonValue = JSON.stringify(tasks); await AsyncStorage.setItem(STORAGE_KEY, jsonValue); } catch (e) { console.error('保存任务失败', e); } }; // 组件挂载时读取任务 useEffect(() => { loadTasks(); }, []); // 任务列表变更时自动保存 useEffect(() => { saveTasks(taskItems); }, [taskItems]); const handleAddTask = () => { Keyboard.dismiss(); setTaskItems([...taskItems, task]); setTask(null); }; const completeTask = (index) => { let itemsCopy = [...taskItems]; itemsCopy.splice(index, 1); setTaskItems(itemsCopy); closeModal(); }; const closeModal = () => { setModalVisable(false); }; const handleRemoveTask = (index) => { setModalVisable(true); }; return ( <View style={styles.container}> <View style={styles.tasksWrapper}> <Text style={styles.sectionTitle}>Your Tasks</Text> <View style={styles.items}> {taskItems.map((item, index) => { return ( <TouchableOpacity key={index} onPress={() => { handleRemoveTask(index); setItemToDelete(index); }} > <Task text={item} /> </TouchableOpacity> ); })} </View> </View> <KeyboardAvoidingView behavior={Platform.OS === "ios" ? "padding" : "height"} style={styles.writeTaskWrapper} > <TextInput style={styles.input} placeholder={"Add a task!"} value={task} onChangeText={(text) => setTask(text)} /> <TouchableOpacity onPress={() => handleAddTask()}> <View style={styles.addWrapped}> <Text style={styles.addText}>+</Text> </View> </TouchableOpacity> </KeyboardAvoidingView> <View style={styles.modalWrapper}> <Modal style={styles.modal} isVisible={modalVisable} onBackdropPress={closeModal} > <Text style={styles.modalText}>Have you completed this task?</Text> <FontAwesomeIcon icon={faTrophy} style={styles.trophyIcon} size={96} /> <View style={styles.horizontalRule}> <Text style={styles.modalDescription}> If you confirm this task is complete it will be deleted and removed from the app permanently </Text> </View> <View style={styles.buttonArea}> <TouchableOpacity style={styles.closeButton} onPress={() => closeModal()} > <Text style={styles.buttonText}>Cancel</Text> </TouchableOpacity> <TouchableOpacity style={styles.completeButton} onPress={() => completeTask(itemToDelete)} > <Text style={styles.buttonText}>Complete Task</Text> </TouchableOpacity> </View> </Modal> </View> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#E8EAED", }, tasksWrapper: { paddingTop: 80, paddingHorizontal: 20, }, sectionTitle: { fontSize: 24, fontWeight: "bold", }, items: { marginTop: 30, }, writeTaskWrapper: { position: "absolute", bottom: 50, width: "100%", flexDirection: "row", justifyContent: "space-around", alignItems: "center", }, input: { paddingVertical: 15, paddingHorizontal: 15, backgroundColor: "#FFF", borderRadius: 60, borderColor: "#C0C0C0", borderWidth: 1, textAlign: "center", width: "70%", }, addWrapped: { width: 60, height: 60, backgroundColor: "#FFF", borderRadius: 60, borderColor: "#C0C0C0", borderWidth: 1, justifyContent: "center", alignItems: "center", }, addText: {}, modalWrapper: {}, modal: { justifyContent: "flex-start", alignSelf: "center", top: 100, borderRadius: 5, backgroundColor: "#FFF", maxWidth: 350, maxHeight: 300, padding: 25, }, modalText: { fontSize: 20, fontWeight: "normal", textAlign: "center", }, buttonText: { fontWeight: "bold", textAlign: "center", }, buttonArea: { position: "relative", flexWrap: 'nowrap', alignContent: "center", justifyContent: "space-between", flexDirection: "row", paddingTop: 5, minWidth: 100, maxWidth: 350, top: 5, }, completeButton: { justifyContent: "center", alignSelf: "center", width: 140, height: 36, borderRadius: 10, backgroundColor: "#B096F9", }, closeButton: { justifyContent: "center", alignSelf: "center", width: 140, height: 36, borderRadius: 10, backgroundColor: "#FF8989", }, trophyIcon: { padding: 75, color: "#F8C511", alignSelf: "center", }, modalDescription: { textAlign: "center", fontSize: 14, borderColor: "#AFAFAF", borderTopWidth: 1, borderBottomWidth: 1, }, });
改动说明
- 引入了
AsyncStorage依赖,新增了存储用的常量key避免拼写错误 - 新增了
loadTasks和saveTasks两个异步方法处理本地数据读写 - 新增两个
useEffect钩子:一个在组件首次挂载时读取本地数据更新任务列表,另一个监听任务列表的变化,每次变更自动同步到本地存储 - 原有业务逻辑完全不需要修改,只需要新增上述逻辑即可实现数据持久化,重启应用后任务不会丢失
内容的提问来源于stack exchange,提问作者StanLachie
相关产品推荐
相关产品推荐

