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