React中如何优雅更新含数组的嵌套State属性?
优化React中嵌套数组State的更新方式
核心优化思路
你的现有代码已经实现功能,但手动多层复制对象和数组的写法比较繁琐。可以通过函数式更新结合map方法,更简洁地完成不可变更新,同时避免闭包导致的state过时问题。
优化后的代码
import { StyleSheet, Text, View, SectionList, TouchableOpacity } from 'react-native'; import { useState } from 'react'; const App = () => { const [data, setData] = useState([ { id: 0, name: "chicago", country: "us", data: [ { temperature: 75, date: '2023-05-18' }, { temperature: 60, date: '2023-05-20' } ] } ]) // 简化后的更新函数 const addOneDegree = (sectionId, itemIndex) => { setData(prevData => prevData.map(section => { // 跳过不需要更新的section if (section.id !== sectionId) return section; // 更新目标section的data数组 return { ...section, data: section.data.map((item, idx) => idx === itemIndex ? {...item, temperature: item.temperature + 1} : item ) }; }) ); } return ( <View style={styles.container}> <SectionList sections={data} keyExtractor={(item, index) => `${item.date}-${index}`} // 更合理的key renderItem={({index, section}) => ( <TouchableOpacity onPress={() => addOneDegree(section.id, index)}> <Text>{section.data[index].temperature}°F - {section.data[index].date}</Text> </TouchableOpacity> )} renderSectionHeader={({section}) => <Text>{section.name} - {section.country}</Text>} /> </View> ); } export default App; const styles = StyleSheet.create({ container: { backgroundColor: '#fff', marginTop: 60 }, });
优化点说明
- 函数式更新:通过
setData(prevData => ...)确保基于最新的state进行修改,避免组件闭包捕获旧state的问题。 - 用map替代手动复制:通过两次
map遍历,只修改需要更新的section和item,其余对象保持原引用,符合React不可变数据的要求,代码更简洁。 - 简化参数传递:只传递
sectionId和itemIndex两个关键标识,无需传递整个item和section对象,逻辑更清晰。 - 优化keyExtractor:用
item.date结合索引生成更稳定的key,避免原写法中item + index可能导致的key冲突。
内容的提问来源于stack exchange,提问作者Keldryn
相关产品推荐
相关产品推荐

