React native 使用异步存储保存列表

React native 使用异步存储保存列表,react-native,asyncstorage,React Native,Asyncstorage,所以我做了一个“记事本”应用程序,我想这样做,用户写的文本等应该保存,这样当用户退出应用程序时,文本不会被重置 我是新手,在谷歌搜索了几次之后,我需要异步存储?让这一切发生。 但真的不知道怎么做 import React, { useState } from 'react'; import { StyleSheet, Text, View, FlatList, TouchableWithoutFeedback, TouchableOpacity, Keyboard, AsyncSto

所以我做了一个“记事本”应用程序,我想这样做,用户写的文本等应该保存,这样当用户退出应用程序时,文本不会被重置

我是新手,在谷歌搜索了几次之后,我需要异步存储?让这一切发生。 但真的不知道怎么做

import React, { useState } from 'react';
import { 
StyleSheet, 
Text, 
View, 
FlatList, 
TouchableWithoutFeedback, 
TouchableOpacity,
Keyboard,
AsyncStorage
} from 'react-native';
import Header from './components/header';
import ListItem from './components/listitem';
import AddList from './components/addlist';

export default function App() {

    const [todos, setTodos] = useState([

    ]);

    const pressHandler = (key) => {
      setTodos((prevTodos) => {
      return prevTodos.filter(todo => todo.key != key);
     });
    }

    const submitHandler = (text) => {
      if(text.length > 0) {
        setTodos((prevTodos) => {
        return [
       { text: text, key: Math.random().toString() },
      ...prevTodos
     ];
   })
   } 
  }

 return (
  <TouchableWithoutFeedback onPress={() => {
    Keyboard.dismiss();
   }}>
  <View style={styles.container}>
    <Header />
     <View style={styles.content}>
      <AddList  submitHandler={submitHandler} />
       <View style={styles.todoList}>
        <FlatList 
          data={todos}
            renderItem={({ item }) => (
            <ListItem item={item} pressHandler={pressHandler} />
           )}
        />
      </View>
     </View>
   </View>
 </TouchableWithoutFeedback>
  );
  }

您可以使用AsyncStorage在本地存储中存储和加载数据。需要注意的一点是,数据必须是字符串,因此任何像对象这样不是字符串的东西都需要字符串化。您可以使用
JSON.stringify(…)
来执行此操作。然后,当您获取字符串时,可以使用
JSON.parse(…)
将其转换回对象

因此,要将当前代码转换为自动加载保存的TODO并始终保存最新的TODO的代码,可以编写以下代码:

import React, { useState, useEffect } from 'react';
import {
  StyleSheet,
  Text,
  View,
  FlatList,
  TouchableWithoutFeedback,
  TouchableOpacity,
  Keyboard,
  AsyncStorage,
  Button
} from 'react-native';
import Header from './components/header';
import ListItem from './components/listitem';
import AddList from './components/addlist';

export default function App() {
  const [todos, setTodos] = useState([]);

  useEffect(() => {
    restoreTodosFromAsync();
  }, []);

  const pressHandler = key => {
    console.log('Todos BEFORE delete');
    console.log(todos);

    const newTodos = todos.filter(todo => todo.key !== key);

    console.log('Todos AFTER delete');
    console.log(todos);

    setTodos(newTodos);
    storeTodosInAsync(newTodos);
  };

  const submitHandler = text => {
    if (text.length === 0) return;

    const key = Math.random().toString();

    console.log('Todos BEFORE submit');
    console.log(todos);

    const newTodos = [{ text, key }, ...todos];

    console.log('Todos AFTER submit');
    console.log(todos);

    setTodos(newTodos);
    storeTodosInAsync(newTodos);
  };

  const asyncStorageKey = '@todos';

  const storeTodosInAsync = newTodos => {
    const stringifiedTodos = JSON.stringify(newTodos);

    AsyncStorage.setItem(asyncStorageKey, stringifiedTodos).catch(err => {
      console.warn('Error storing todos in Async');
      console.warn(err);
    });
  };

  const restoreTodosFromAsync = () => {
    AsyncStorage.getItem(asyncStorageKey)
      .then(stringifiedTodos => {
        console.log('Restored Todos:');
        console.log(stringifiedTodos);

        const parsedTodos = JSON.parse(stringifiedTodos);

        if (!parsedTodos || typeof parsedTodos !== 'object') return;

        setTodos(parsedTodos);
      })
      .catch(err => {
        console.warn('Error restoring todos from async');
        console.warn(err);
      });
  };

  return (
    <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
      <View style={styles.container}>
        <Header />
        <View style={styles.content}>
          <AddList submitHandler={submitHandler} />
          <View style={styles.todoList}>
            <FlatList
              data={todos}
              renderItem={({ item }) => <ListItem item={item} pressHandler={pressHandler} />}
            />
          </View>
        </View>
      </View>
    </TouchableWithoutFeedback>
  );
}
import React,{useState,useffect}来自“React”;
进口{
样式表,
文本,
看法
平面列表,
可触摸且无反馈,
可触摸不透明度,
键盘
异步存储,
按钮
}从“反应本机”;
从“./components/Header”导入标题;
从“./components/ListItem”导入ListItem;
从“./components/AddList”导入AddList;
导出默认函数App(){
const[todos,setTodos]=useState([]);
useffect(()=>{
restoreTodosFromAsync();
}, []);
const pressHandler=key=>{
log('delete之前的TODO');
控制台日志(todos);
常量newTodos=todos.filter(todo=>todo.key!==key);
log(“删除后的TODO”);
控制台日志(todos);
setTodos(newTodos);
storeTodosInAsync(newTodos);
};
常量submitHandler=文本=>{
如果(text.length==0)返回;
const key=Math.random().toString();
console.log('Todos BEFORE submit');
控制台日志(todos);
常量newTodos=[{text,key},…todos];
log('submit之后的TODO');
控制台日志(todos);
setTodos(newTodos);
storeTodosInAsync(newTodos);
};
常量asyncStorageKey='@todos';
const storeTodosInAsync=newTodos=>{
const stringifiedTodos=JSON.stringify(newTodos);
setItem(asyncStorageKey,stringifiedTodos).catch(err=>{
console.warn('异步存储TODO时出错');
控制台。警告(错误);
});
};
const restoreTodosFromAsync=()=>{
AsyncStorage.getItem(asyncStorageKey)
.然后(stringifiedTodos=>{
log('restoredtodos:');
控制台日志(stringifiedTodos);
const parsedTodos=JSON.parse(stringifiedTodos);
如果(!parsedTodos | | typeof parsedTodos!=“object”)返回;
setTodos(解析的todos);
})
.catch(错误=>{
warn('Error restoring todo from async');
控制台。警告(错误);
});
};
返回(
}
/>
);
}

谢谢您的帮助,但当我按save时,在重新加载应用程序时,不保存任何内容。如果我按restore,便笺就会回来。也许这是因为我有addlist.js和listitem.js,然后通过在应用程序中乱搞而导入到app.js。我想到了“保存”按钮可以工作,但只有在删除注释后才可以恢复按钮。现在,在几天不处理项目后,应用程序不能使用异步存储,只有在我删除了您需要的代码后才能工作补充。我不知道在我问这个问题的那天它是如何工作的。代码编辑器(vs studio)中没有错误,但是在expo上它抛出了错误(传播非iterible实例的尝试无效)。我还没有在google或stackoverflow上找到解决方案,这就是我再次询问的原因。代码与上面的答案相同。TypeError:传播不可复制实例的尝试无效。这个错误位于:在App(在withexpoot.js:26)在RootErrorBoundary(在withexpoot.js:25)在expoot(atrenderApplication.js:40)在RCTView(在Appcontainer.js:101)在RCTView(在Appcontainer.js:119)在Appcontainer(在renderApplication.js:39)我对这个evan的意思没有任何疑问。哦,应用程序加载了ui,但当我按add everything时崩溃并抛出此错误。我没有从console.log中得到任何东西。我是否将console.log放在了正确的位置?查看上面更新的代码,看看我把console.log放在哪里了
import React, { useState, useEffect } from 'react';
import {
  StyleSheet,
  Text,
  View,
  FlatList,
  TouchableWithoutFeedback,
  TouchableOpacity,
  Keyboard,
  AsyncStorage,
  Button
} from 'react-native';
import Header from './components/header';
import ListItem from './components/listitem';
import AddList from './components/addlist';

export default function App() {
  const [todos, setTodos] = useState([]);

  useEffect(() => {
    restoreTodosFromAsync();
  }, []);

  const pressHandler = key => {
    console.log('Todos BEFORE delete');
    console.log(todos);

    const newTodos = todos.filter(todo => todo.key !== key);

    console.log('Todos AFTER delete');
    console.log(todos);

    setTodos(newTodos);
    storeTodosInAsync(newTodos);
  };

  const submitHandler = text => {
    if (text.length === 0) return;

    const key = Math.random().toString();

    console.log('Todos BEFORE submit');
    console.log(todos);

    const newTodos = [{ text, key }, ...todos];

    console.log('Todos AFTER submit');
    console.log(todos);

    setTodos(newTodos);
    storeTodosInAsync(newTodos);
  };

  const asyncStorageKey = '@todos';

  const storeTodosInAsync = newTodos => {
    const stringifiedTodos = JSON.stringify(newTodos);

    AsyncStorage.setItem(asyncStorageKey, stringifiedTodos).catch(err => {
      console.warn('Error storing todos in Async');
      console.warn(err);
    });
  };

  const restoreTodosFromAsync = () => {
    AsyncStorage.getItem(asyncStorageKey)
      .then(stringifiedTodos => {
        console.log('Restored Todos:');
        console.log(stringifiedTodos);

        const parsedTodos = JSON.parse(stringifiedTodos);

        if (!parsedTodos || typeof parsedTodos !== 'object') return;

        setTodos(parsedTodos);
      })
      .catch(err => {
        console.warn('Error restoring todos from async');
        console.warn(err);
      });
  };

  return (
    <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
      <View style={styles.container}>
        <Header />
        <View style={styles.content}>
          <AddList submitHandler={submitHandler} />
          <View style={styles.todoList}>
            <FlatList
              data={todos}
              renderItem={({ item }) => <ListItem item={item} pressHandler={pressHandler} />}
            />
          </View>
        </View>
      </View>
    </TouchableWithoutFeedback>
  );
}