【问题标题】:Saving list with AsyncStorage使用 AsyncStorage 保存列表
【发布时间】:2020-01-18 14:07:39
【问题描述】:

所以我制作了一个“记事本”应用程序,并且我想要保存用户写的文本等它应该被保存,所以当用户退出应用程序时文本不会被重置。

我是 react-native 的新手,经过几次谷歌搜索后,我需要 AsyncStorage?实现这一目标。 但真的不知道该怎么做。

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>
  );
  }

突然出现的新问题在没有接触代码的情况下就被破解了

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

      storeTodosInAsync(newTodos);

      console.log(prevTodos);
    return newTodos;

    });


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

        storeTodosInAsync(newTodos);
        console.log(newTodos);
        return newTodos;
     });
   }
 };

【问题讨论】:

    标签: react-native asyncstorage


    【解决方案1】:

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

    因此,要将您当前的代码转换为自动加载已保存的待办事项并始终保存最新的内容,您可以这样写:

        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>
          );
        }
    

    【讨论】:

    • 感谢您的帮助,但是当我按下保存时,什么都没有保存,当我重新加载应用程序时,什么都没有。如果我按恢复笔记回来。也许这是因为我有 addlist.js 和 listitem.js 然后导入到 app.js
    • 通过在应用程序中搞砸,我想出了保存按钮的工作,但仅在删除笔记时用于恢复按钮。
    • 现在在几天没有处理该项目后,该应用程序不适用于 asyncstorage 它只有在我删除您添加的代码时才有效。我不知道在我问这个问题的那天它是如何工作的。代码编辑器(vs studio)中没有错误,但在博览会上它抛出错误(传播不可迭代实例的无效尝试)我没有在谷歌或stackoverflow上找到解决方案,这就是我再次在这里询问的原因。该代码与您上面的答案相同。
    • TypeError:传播不可迭代实例的尝试无效。此错误位于: 在 App (at withExpoRoot.js:26) in RootErrorBoundary (at withExpoRoot.js:25) in ExpoRoot (atrenderApplication.js:40) in RCTView (at Appcontainer.js:101) in RCTView (at Appcontainer .js:119)在 AppContainer 中(在 renderApplication.js:39 处)我对这个 evan 的含义的定义为零。哦,应用程序加载了用户界面,但是当我按下添加时,一切都会崩溃并抛出这个错误。
    • 我没有从 console.log 中得到任何东西我把 console.log 放在正确的地方了吗?查看上面更新的代码,看看我把 console.log 放在哪里
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多