【发布时间】:2021-11-11 02:15:53
【问题描述】:
我正在尝试在 useState 挂钩中使用 ASyncStorage 从存储中加载数据(如果存在)。 我在 map 函数中渲染 todos,但在此之前我正在检查 todos 是未定义还是 []。 如果数据不存在但未定义,则逻辑应将 [] 返回到 useState!
代码如下:
export default function App() {
const [todo, setTodo] = useState('');
const [todos, setTodos] = useState(async () => {
try {
const value = await AsyncStorage.getItem('@MySuperStore:key');
// We have data!!
return value ? JSON.parse(value) : [];
} catch (error) {
// Error retrieving data
console.log(error);
}
});
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(newTodos).then(_retrieveData());
// setTodos(newTodos);
}
};
const deleteTodo = (idx) => {
setTodos(todos.filter((todo, id) => id !== idx));
};
const _storeData = async (value) => {
try {
await AsyncStorage.setItem('@MySuperStore:key', JSON.stringify(value));
} catch (error) {
// Error saving data
console.log(error);
}
};
const _retrieveData = async () => {
try {
const value = await AsyncStorage.getItem('@MySuperStore:key');
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 === [] || todos === undefined ? (
<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>
);
}
【问题讨论】:
-
=== []永远不会是真的,因为比较是通过引用进行的,但这不是问题。请注意它说的是undefined is not a function而不是Cannot read properties of undefined (reading 'map'),所以显然todos不是未定义的,但也没有属性map,这意味着它是something 但可能不是数组。检查你的开发工具它实际上是什么。也许这是一个承诺。 -
这个错误其实是来自useState钩子里面try-catch的catch块。 App.js:22 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'getItem')
-
你一个权利最初的承诺是返回的。
标签: javascript reactjs react-native react-hooks