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

React state中存储的数组更新异常,下拉筛选数组未按预期更新是什么原因?

问题根因

  • React的状态更新是异步的,在onChange回调中执行setlocation后立刻调用filterLocations,此时函数内部读取的location还是更新前的旧值,拿不到最新的输入内容。
  • 筛选逻辑存在漏洞:遍历allLocations的过程中,只要遇到一个不匹配的元素就直接清空dropDownLocations,会把之前已经匹配到的结果全部清除;同时循环内多次调用setdropDownLocations,由于状态更新的批量合并特性,每次读取的dropDownLocations都是遍历开始前的旧值,无法正确累加匹配结果。
  • 没有在每次筛选前清理上一次的匹配结果,会导致多次输入的结果混乱叠加。

修正后代码

import "./App.css";
import { useState, useEffect } from "react";

function App() {
  // 用户输入的位置
  const [location, setLocation] = useState("");
  const [allLocations, setAllLocations] = useState(["F-1", "F-2", "G-1", "G-2"]);
  const [dropDownLocations, setDropDownLocations] = useState([]);

  // 监听location变化,自动触发筛选
  useEffect(() => {
    // 直接用filter方法一次性筛选所有符合条件的元素
    const matchedLocations = allLocations.filter(item => item.includes(location));
    setDropDownLocations(matchedLocations);
  }, [location, allLocations]);

  return (
    <div className="App">
      <div>
        <input
          value={location}
          onChange={(e) => setLocation(e.target.value)}
        />
        <ul>
          {dropDownLocations.map((i) => (
            <li key={i}>{i}</li>
          ))}
        </ul>
      </div>
    </div>
  );
}

export default App;

修正说明

  • 用useEffect监听location的变化,每次输入更新location完成后再执行筛选逻辑,保证拿到的是最新的输入值
  • 直接通过Array.filter方法一次性得到所有匹配的结果,统一调用setDropDownLocations更新状态,避免了循环内多次更新状态的问题
  • 每次筛选都会生成全新的匹配结果数组,直接覆盖旧的下拉选项数组,不需要手动清空,也不会出现结果叠加的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 11:42:00