React Native深拷贝数据更新问题:普通变量与useState使用异常如何解决
问题根源分析
- 普通
var声明变量拿不到值的原因:React函数组件每次重渲染都会重新执行整个函数体,你用var/let声明的临时变量会在每次渲染时被重置为初始值{},之前在事件回调里的赋值会在重渲染后丢失,所以打印为空。 useState使用时提前修改props的原因:首先你直接修改data[0].atpData的操作本身违反了React props只读的规则,props是父组件传入的引用类型数据,直接修改属性会同步变更父组件的原始数据。如果在useState赋值阶段就出现数据变更,说明你用的扩展运算符...是浅拷贝,若atpData内部存在嵌套的引用类型值,修改tempData的嵌套属性时会联动修改原props里的对象。
解决方案
- 本地临时状态统一用
useState存储,避免渲染重置丢失数据 - 对需要修改的props数据做深拷贝,切断和原props数据的引用关联
- 禁止直接修改props,通过父组件传递的回调函数来更新原始数据
修正后代码示例
const HomeProfile = ({data, updateAtpData}) => { // 用useState存储临时数据,避免渲染重置 const [tempData, setTempData] = useState({}) const onOptionClick = (clicked_index) => { // 深拷贝原数据,切断和props的引用关联,避免意外修改原数据 const copyAtpData = JSON.parse(JSON.stringify(data[0].atpData)) copyAtpData.selected_index = clicked_index setTempData(copyAtpData) } const addInProps = () => { // 调用父组件传入的回调修改原始数据,不要直接改props updateAtpData(tempData) } const checkData = () => { console.log('tempData', tempData) } return( <View> <Text></Text> </View> ) }
补充说明:如果你的atpData里包含函数、正则、Date等特殊类型,JSON序列化的深拷贝方式会丢失这些类型,可以自行实现深拷贝逻辑,或者使用不可变数据工具来处理。
内容的提问来源于stack exchange,提问作者Rambler
相关产品推荐
相关产品推荐

