You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:59:42