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

React函数组件:更新状态的onClick事件处理函数异常问题

问题原因

你遇到的问题根源在于Array.prototype.push()方法的返回值——它不会返回新数组,而是返回数组更新后的长度。第一次点击按钮时,timeList.push(time)给空数组添加一个元素,返回长度1,你把这个数字赋值给newTimeList后更新状态,导致timeList变成了数字类型,后续的length判断自然失效。

修复方法

要正确更新数组状态,必须创建新数组(React状态是不可变的,直接修改原数组不会触发组件重新渲染),以下是两种常用方式:

方式1:展开运算符生成新数组

const handleClick = () => {
  if (time) {
    // 展开原数组元素,追加新时间,生成全新数组
    const newTimeList = [...timeList, time];
    setTimeList(newTimeList);
  }
};

方式2:使用concat方法创建新数组

const handleClick = () => {
  if (time) {
    // concat返回拼接后的新数组,不会修改原数组
    const newTimeList = timeList.concat(time);
    setTimeList(newTimeList);
  }
};

更安全的函数式更新写法

如果状态更新依赖前一次的状态值,推荐用函数式更新,避免闭包导致的状态过期问题:

const handleClick = () => {
  if (time) {
    setTimeList(prevList => [...prevList, time]);
  }
};
额外小问题修复

除核心bug外,代码还有两处细节问题:

  1. 列表渲染错误:showTimeList里的map返回<p>item</p>,会固定渲染字符串"item",而非数组中的时间值,同时需添加key属性:
const timesArr = timeList.map((item, index) => {
  return <p key={index}>{item}</p>;
});
  1. useEffect无限循环:原代码依赖time,每次setTime都会触发useEffect重新执行calcTime,形成无限循环。应改为空依赖仅挂载时执行,再通过递归实现持续更新:
useEffect(() => {
  calcTime();
}, []); // 空依赖,仅组件挂载时执行一次

const calcTime = () => {
  setTimeout(() => {
    const today = new Date();
    const timeNow = `${today.getHours()}:${today.getMinutes()}:${today.getSeconds()}`;
    setTime(timeNow);
    // 递归调用,保持每5秒更新一次时间
    calcTime();
  }, 5000);
};

内容的提问来源于stack exchange,提问作者NewToJS

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 20:25:22