javascript - 使用 AsyncStorage 时未加载待办事项
问题描述
我正在尝试使用 AsyncStorage 从 useEffect 挂钩中获取我的待办事项。如果没有待办事项(意思是待办事项 === [])然后文本组件显示“添加待办事项”。
最初,待办事项在 useState 挂钩中设置为“[]”。当在 onPress 调用 addItem() 方法时,todos 没有加载。
我不知道为什么会这样……
export default function App() {
const [todo, setTodo] = useState('');
const [todos, setTodos] = useState([]);
useEffect(() => {
_retrieveData();
}, [todos]);
const addItem = (newTodo) => {
if (newTodo.length === 0) {
Alert.alert(
'Enter a String',
'You have entered a string with 0 characters',
[{ text: 'Okay', style: 'default' }]
);
} else {
console.log(newTodo);
let newTodos = [newTodo, ...todos];
setTodo('');
_storeData(JSON.stringify(newTodos));
}
};
const deleteTodo = (idx) => {
setTodos(todos.filter((todo, id) => id !== idx));
};
const _storeData = async (value) => {
try {
await AsyncStorage.setItem('TASKS', value);
} catch (error) {
// Error saving data
console.log(e);
}
};
const _retrieveData = async () => {
try {
const value = await AsyncStorage.getItem('TASKS');
if (value !== null) {
// We have data!!
setTodos(JSON.parse(value));
console.log(value);
}
} catch (error) {
// Error retrieving data
console.log(error);
}
};
return (
<TouchableWithoutFeedback
onPress={() => {
Keyboard.dismiss();
}}
>
<View style={styles.outerContainer}>
<Text style={styles.header}>TODO</Text>
<View style={styles.container}>
<TextInput
placeholder='new todo'
style={styles.input}
value={todo}
onChangeText={(text) => {
setTodo(text);
}}
></TextInput>
<Button title='Add' onPress={() => addItem(todo)}></Button>
</View>
<ScrollView style={styles.scrollView}>
{todos === [] ? (
<View>
<Text>Add a todo!</Text>
</View>
) : (
todos.map((todo, idx) => (
<View style={styles.todo} key={idx}>
<Text style={styles.todoText}>{todo}</Text>
<View style={styles.delete}>
<Button
color='red'
title='Delete'
onPress={() => deleteTodo(idx)}
></Button>
</View>
</View>
))
)}
</ScrollView>
</View>
</TouchableWithoutFeedback>
);
}
解决方案
不要使用传递todo
值newTodo
,因为setState
不会async
立即执行,因此您可以使用当前设置todo
的值而不是传递旧值,
const addItem = (newTodo) => {
if (todo.length === 0) {
Alert.alert(
'Enter a String',
'You have entered a string with 0 characters',
[{ text: 'Okay', style: 'default' }]
);
} else {
console.log(todo);
let newTodos = [todo, ...todos];
setTodo('');
_storeData(JSON.stringify(newTodos));
setTodos(newTodos);
}
};
推荐阅读
- typescript - 声明一个接口,该接口充当起点为 1 的数组
- php - 我验证了我的应用程序如何使用谷歌表修复“此应用程序未验证”
- python - 如何在 Mac 上将 python/pygame 文件转换为可执行文件?
- curl - 使用 curl 从 textreader.surge.sh 下载音频文件
- telnet - 如何在qnx中运行telnet
- mysql - 如何使用 Spring Boot Rest API 在移动应用程序(React Native 或 Ionic)中获取推送通知
- python - Python枚举删除列表的最后一个元素
- ios - 提高标签栏的上边框线
- html - 为什么当我使用图像作为链接时浏览器不显示任何内容
- python - 从 HackerRank 确定 DNA 健康算法的 Python 实现