React中循环使用useState更新状态时报object is undefined问题咨询
问题复现代码
import React from 'react'; import { Button, Image, StyleSheet, Text, View } from 'react-native'; function App() { const firstCategory = [ { id: 1, name: 'person1' }, { id: 2, name: 'person2' }, { id: 3, name: 'person3' }, { id: 4, name: 'person4' }, ]; const [secondCategory, setSecondCategory] = React.useState([ { id: 5, name: 'person5' }, { id: 6, name: 'person6' }, { id: 7, name: 'person7' }, { id: 8, name: 'person8' }, ]); React.useEffect(() => { setSecondCategory([]); for (var i = 0; i < firstCategory.length; i++) { setSecondCategory((secondCategoryArray) => [...secondCategoryArray, firstCategory[i]]); } },[]); return ( <View> {secondCategory.map((item) => { return <Text>{item.name}</Text>; })} </View> ); } export default App;
错误原因
问题由两个特性共同导致:
var声明的变量没有块级作用域,存在作用域提升
你循环中用var声明的迭代变量i在整个useEffect回调的作用域内只有唯一实例,循环执行完成后,i的值会变为4(firstCategory数组长度为4,循环终止时i满足i >= firstCategory.length)。
React的状态更新是异步批量执行的,等你在循环中调用的四次setSecondCategory的回调函数实际执行时,循环已经结束,此时firstCategory[i]等价于firstCategory[4],数组无下标为4的元素,值为undefined。- 函数式状态更新的特性
你使用的函数式更新可以拿到上一次更新后的最新状态,所以四次执行会依次往空数组里追加值,但是每次追加的都是undefined,最终得到的secondCategory就是[undefined, undefined, undefined, undefined],渲染时读取undefined的name属性就会抛出对应的报错。
快速修复方案(仅针对该写法的问题,不改变原有逻辑结构)
将循环里的var i = 0修改为let i = 0,let声明的变量有块级作用域,每次循环都会生成独立的i实例,状态更新回调执行时拿到的就是对应循环次的i值,就能正确追加元素。
当然更合理的实现是直接在useEffect中执行setSecondCategory([...firstCategory]),不需要循环调用状态更新函数,性能更高也更容易维护。
内容的提问来源于stack exchange,提问作者colder programmer
相关产品推荐
相关产品推荐

