You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 03:06:01