React Native中如何将里程状态对象存入Async Storage并读取?
React Native跑步应用:每日里程的Async Storage存储与读取方案
1. 安装Async Storage依赖
首先安装官方维护的Async Storage库:
npm install @react-native-async-storage/async-storage # 或使用yarn yarn add @react-native-async-storage/async-storage
Expo项目无需额外配置,原生项目需按官方文档完成链接配置。
2. 实现基础状态更新函数
补全handleChange函数,将输入字符串转为数字并更新状态:
const handleChange = (day, value) => { // 空输入设为0,否则转为数字 const numericValue = value ? Number(value) : 0; setMiles(prev => ({ ...prev, [day]: numericValue })); };
3. 保存里程数据到Async Storage
实现保存函数,将整个里程对象转为JSON字符串存储(键名用weeklyRunningMiles便于识别):
import AsyncStorage from '@react-native-async-storage/async-storage'; const saveMilesToStorage = async () => { try { const jsonValue = JSON.stringify(miles); await AsyncStorage.setItem('weeklyRunningMiles', jsonValue); console.log('里程数据保存成功'); } catch (e) { console.error('保存数据失败:', e); } };
给每个TouchableOpacity绑定点击事件:
<TouchableOpacity onPress={saveMilesToStorage}> <Text>Submit</Text> </TouchableOpacity>
如果需要单独保存单日数据,可修改函数接收day参数,但保存整个对象更便于后续统一读取。
4. 从Async Storage读取数据
在组件挂载时读取存储的里程数据,更新状态:
useEffect(() => { const loadMilesFromStorage = async () => { try { const jsonValue = await AsyncStorage.getItem('weeklyRunningMiles'); if (jsonValue != null) { setMiles(JSON.parse(jsonValue)); } } catch (e) { console.error('读取数据失败:', e); } }; loadMilesFromStorage(); }, []);
5. 完整代码示例
整合后的组件代码(优化了重复代码,用循环渲染每日输入项):
import React, { useState, useEffect } from 'react'; import { View, Text, TextInput, TouchableOpacity, StyleSheet } from 'react-native'; import AsyncStorage from '@react-native-async-storage/async-storage'; const RunningTracker = () => { const [miles, setMiles] = useState({ monday: 0, tuesday: 0, wednesday: 0, thursday: 0, friday: 0, saturday: 0, sunday: 0, }); // 更新单日里程状态 const handleChange = (day, value) => { const numericValue = value ? Number(value) : 0; setMiles(prev => ({ ...prev, [day]: numericValue })); }; // 保存数据到Async Storage const saveMilesToStorage = async () => { try { const jsonValue = JSON.stringify(miles); await AsyncStorage.setItem('weeklyRunningMiles', jsonValue); console.log('里程数据已保存'); } catch (e) { console.error('保存失败:', e); } }; // 组件挂载时读取数据 useEffect(() => { const loadMiles = async () => { try { const storedData = await AsyncStorage.getItem('weeklyRunningMiles'); if (storedData) { setMiles(JSON.parse(storedData)); } } catch (e) { console.error('读取失败:', e); } }; loadMiles(); }, []); return ( <View style={styles.weekDayContainer}> {Object.entries(miles).map(([day, value]) => ( <View key={day} style={styles.milesInput}> <Text style={styles.weekDayText}> {day.charAt(0).toUpperCase() + day.slice(1)} </Text> <TextInput style={styles.weekDayInput} placeholder="enter miles" keyboardType="numeric" value={String(value)} onChangeText={(input) => handleChange(day, input)} /> <TouchableOpacity onPress={saveMilesToStorage}> <Text>Submit</Text> </TouchableOpacity> </View> ))} </View> ); }; const styles = StyleSheet.create({ weekDayContainer: { padding: 20, gap: 15, }, milesInput: { flexDirection: 'row', alignItems: 'center', gap: 10, }, weekDayText: { width: 80, fontSize: 16, }, weekDayInput: { flex: 1, borderWidth: 1, borderColor: '#ccc', padding: 8, borderRadius: 4, }, }); export default RunningTracker;
注意事项
- TextInput的
value必须转为字符串,直接传递数字会触发React Native警告 - Async Storage操作是异步的,必须用
async/await或Promise处理 - 建议给存储键名设置有意义的名称,避免与其他存储数据冲突
- 可根据需求优化:比如仅保存修改的单日数据,或添加保存成功的Toast提示
内容的提问来源于stack exchange,提问作者Tony
相关产品推荐
相关产品推荐

