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

React JS下拉切换时数组未清空导致旧数据累积问题

问题根因

你的代码出现旧数据残留是几个明确的逻辑错误导致的:

  • 开头写的数组清空逻辑完全无效:你刚声明var newArray = []时这个数组本身就是空的,对空数组执行forEach遍历加splice删除没有任何实际作用。
  • 清空逻辑执行完后你写了newArray = this.state.data.slice(),直接把state里存储的上一次加载的旧数据完整拷贝到了新数组里,后续接口返回数据你是往这个已经带了旧数据的数组里push,自然会把新旧数据拼接到一起,长度持续增长。
  • 存在请求竞态隐患:如果用户快速切换下拉选项,多个接口请求的返回顺序不可控,可能出现后选的选项先返回、先选的选项后返回的情况,最终页面会展示错误的旧数据。
  • 额外的渲染逻辑错误:你在接口请求的回调里手动调用fetchChart(),但React组件的state更新会自动触发重渲染,手动调用渲染方法会导致状态和视图不同步。
修复步骤
  • 删除完全无效的空数组遍历清空代码,接口返回数据后不要基于旧state的data做拼接,直接用接口返回的全新数据构造数组。
  • 增加请求ID标记,处理快速切换下拉的竞态问题,只有最后一次触发的请求返回结果才允许更新state。
  • 删掉接口回调里手动调用fetchChart()的代码,state更新后render函数会自动重新执行,渲染最新的图表数据。
  • 去掉render里对事件处理函数的bind调用,你已经用类箭头函数的写法定义了onDropdownChange,本身已经绑定了this,每次render都bind会生成新的函数实例,触发不必要的组件重渲染。
修正后完整代码
import React from 'react';
import axios from 'axios';
// 其他组件导入省略:CustomLineChart、CustomDropdownList

class Dashboard extends React.Component {
  // 用于标记最新请求ID,处理竞态问题
  latestRequestId = 0;

  state = {
    data: [],
    items: []
  }

  onDropdownChange = (selectedVal) => {
    // 每次触发下拉切换,自增请求ID,记录当前是最新一次请求
    const currentRequestId = ++this.latestRequestId;
    const url = `https://abcdefgh...../${selectedVal}/readings?today`;

    axios.get(url).then(res => {
      // 如果当前请求不是最新触发的,直接丢弃结果,避免旧数据覆盖新数据
      if (currentRequestId !== this.latestRequestId) return;

      // 直接从接口返回数据构造新数组,完全不引用旧的state数据,从根源避免旧数据残留
      const responseItems = res.data.items;
      const newArray = responseItems.map(item => ({
        time: item.dateTime,
        TM: item.value
      }));

      // 排序后更新state,state更新会自动触发组件重渲染
      const sortedArray = newArray.sort((a, b) => new Date(a.time).getTime() - new Date(b.time).getTime());
      this.setState({ 
        data: sortedArray,
        items: responseItems
      });
    });
  }

  render() {
    const { items, data } = this.state;
    const itemList = items.map(item => {
      return <tr key={`${item.dateTime}${item.value}`}>
        <td style={{whiteSpace: 'nowrap'}}>{item.dateTime}</td>
        <td>{item.measure}</td>
        <td>{item.value}</td>
      </tr>
    });

    return (
      <div>   
        <CustomLineChart data={data} />
        <CustomDropdownList changeLink={this.onDropdownChange} />
        {/* 如需渲染表格,放开下方注释即可 */}
        {/* <table><tbody>{itemList}</tbody></table> */}
      </div>
    );
  }
}

export default Dashboard;

补充说明:原来代码里fetchChart方法没有实际存在的必要,直接在render里渲染图表组件即可,逻辑更清晰也更符合React的单向数据流规则。

内容的提问来源于stack exchange,提问作者chk.buddi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 05:12:35