React Hooks从数组选随机对象时函数报错,求排查解决
问题分析与解决方案
嘿,我来帮你揪出问题根源!你遇到的TypeError: Cannot read property 'length' of undefined错误主要来自两个细节问题,咱们一步步拆解:
1. 事件回调的参数传递错误
你定义的randomCities函数写了(e, cities)两个参数,但React的onClick回调默认只会传递事件对象e作为第一个参数,第二个cities参数根本没被传入,所以它的值是undefined——这时候访问cities.length自然就会报错。
而且组件里已经通过useState声明了cities状态,函数可以直接访问组件作用域里的cities变量,完全不需要额外把它当参数传进去。
2. 状态更新的类型不匹配
你的初始cities状态是一个数组,但你在setCities时,把单个城市对象(比如{ nameCity: 'Kraków' })直接赋值给了它。这样更新后,cities就从数组变成了单个对象,后续执行cities.map时又会报错,因为对象没有map方法。
修正后的完整代码
import React, { useState } from 'react'; export default function AppHooks() { const [cities, setCities] = useState([ { nameCity: 'Kraków' }, { nameCity: "Kielce" } ]); // 移除多余的cities参数,直接用组件作用域内的状态 function randomCities(e) { const len = cities.length; const randomCity = cities[Math.floor(Math.random() * len)]; // 保持状态为数组类型,把选中的城市放进新数组 setCities([randomCity]); } let citi = cities.map((cit, i) => { return (<div key={i}> {cit.nameCity} </div>) }) return ( <div> {citi} <button onClick={randomCities}> Change</button> </div> ) }
额外优化建议
如果你只是想显示随机城市,可以单独维护一个currentCity状态来保存当前显示的城市,原城市数组作为数据源保持不变,逻辑会更清晰:
import React, { useState } from 'react'; export default function AppHooks() { // 固定的城市数据源 const cityList = [ { nameCity: 'Kraków' }, { nameCity: "Kielce" } ]; // 单独维护当前显示的城市状态 const [currentCity, setCurrentCity] = useState(cityList[0]); function randomCities() { const randomIndex = Math.floor(Math.random() * cityList.length); setCurrentCity(cityList[randomIndex]); } return ( <div> <div>{currentCity.nameCity}</div> <button onClick={randomCities}> Change</button> </div> ) }
内容的提问来源于stack exchange,提问作者SeN
相关产品推荐
相关产品推荐

