React Native中AsyncStorage存入useState后map报错求助
解决React Native中AsyncStorage数据存入useState后map报错问题
问题描述
首次尝试React Native开发,尝试将AsyncStorage.getItem获取的数据存入useState后通过map渲染,频繁出现"Error map undefined"错误;但直接在State数组中赋值则可正常运行,已尝试JSON.stringify和JSON.parse仍无法解决。
错误原因分析
- 若
AsyncStorage中曾存储过非数组格式的数据,JSON.parse后会得到非数组类型,导致调用map时报错;首次运行无存储数据时虽不会触发setValue,但如果解析过程出现异常,也可能导致value变为非数组。 saveOption中直接依赖当前value状态,存在闭包问题,可能导致状态更新不及时或异常。- 组件函数体中直接调用
AsyncStorage.getItem属于冗余操作,每次渲染都会执行,无实际作用还可能干扰状态判断。
解决方案及修改后的代码
import { useEffect, useState } from 'react'; import { View, Text, StyleSheet } from 'react-native'; import RadioForm from 'react-native-simple-radio-button'; import AsyncStorage from '@react-native-async-storage/async-storage'; const SelectOption = () => { const [value, setValue] = useState([]); // 用函数式更新避免闭包导致的状态异常 const saveOption = (item) => { try { setValue(prevValue => [...prevValue, {name: item, id: Math.random()}]); } catch (e) { console.log(e); } }; useEffect(() => { AsyncStorage.setItem('option', JSON.stringify(value)); }, [value]); useEffect(() => { const getOption = async () => { try { const jsonValue = await AsyncStorage.getItem('option'); // 确保解析后是数组,无数据则设为空数组 const parsedData = jsonValue ? JSON.parse(jsonValue) : []; // 强制校验类型,非数组则重置为空数组 setValue(Array.isArray(parsedData) ? parsedData : []); } catch (e) { console.log(e); // 解析出错时也重置为空数组,避免后续渲染报错 setValue([]); } }; getOption(); }, []); const radioProps = [ {label: 'Option 1', value: 'option1'}, {label: 'Option 2', value: 'option2'}, {label: 'Option 3', value: 'option3'} ]; return ( <View style={styles.sectionContainer}> <RadioForm radio_props={radioProps} initial={0} onPress={(selectedValue) => { saveOption(selectedValue); }} /> {/* 渲染前先判断是否为数组,彻底避免map调用在非数组上 */} {Array.isArray(value) && value.map((item) => { return <Text key={item.id}>{item.name}</Text>; })} </View> ); }; const styles = StyleSheet.create({ sectionContainer: { flex: 1, alignItems: 'center', justifyContent: 'center', }, }); export default SelectOption;
关键修改点说明
- 函数式状态更新:
saveOption中使用prevValue获取最新状态,解决闭包导致的状态更新异常问题。 - 严格数据校验:从
AsyncStorage取数据时,强制保证最终存入状态的是数组,无数据或解析失败都设置为空数组。 - 渲染前类型判断:在
map执行前增加Array.isArray(value)判断,确保只有数组才会执行遍历渲染。 - 移除冗余操作:删除组件函数体中直接调用的
AsyncStorage.getItem,避免不必要的重复执行。
内容的提问来源于stack exchange,提问作者Lunasha
相关产品推荐
相关产品推荐

