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

React中使用datalist出现Maximum Call Stack Size Exceeded错误,如何排查?

排查React渲染大量<option>触发调用栈溢出的问题

核心诱因

你从FDA API拉取了38647条药品名称,直接全部渲染到<datalist>里,这会触发React递归渲染虚拟DOM时超出JavaScript调用栈的限制——JavaScript的调用栈深度有限,几万级别的子元素递归遍历必然撑爆栈。

排查步骤

  • 确认数据量级:查看console.log(drugs)的输出长度,你这里明确是3万+,这就是问题根源。
  • 缩小数据测试:临时把API的limit改成100,重新运行组件,如果不再报错,就实锤是大量DOM元素导致的渲染栈问题。
  • 排除无限重渲染:检查useEffect依赖项是空数组,只会触发一次setData;再确认data没有在渲染过程中被意外修改,排除无限重渲染的可能。

解决办法

1. 搜索过滤+限制渲染数量(最优方案)

原生<datalist>本来就不适合处理超大量数据,直接根据输入值过滤结果,只渲染匹配的前几十条:

const { useState, useEffect } = React

function App() {
  const [data, setData] = useState([])
  const [searchVal, setSearchVal] = useState('')
  const [filteredDrugs, setFilteredDrugs] = useState([])

  useEffect(() => {
    fetch('https://api.fda.gov/drug/label.json?count=openfda.brand_name.exact&limit=38647')
      .then(res => res.json())
      .then(json => {
        const drugs = json.results.map(i => i.term)
        setData(drugs)
      })
      .catch(err => console.error(err))
  }, [])

  // 根据输入过滤药品,只取前100条
  useEffect(() => {
    if (!searchVal) {
      setFilteredDrugs([])
      return
    }
    const matches = data.filter(drug => 
      drug.toLowerCase().includes(searchVal.toLowerCase())
    ).slice(0, 100)
    setFilteredDrugs(matches)
  }, [searchVal, data])

  return (
    <div>
      <input 
        list='drugs' 
        value={searchVal}
        onChange={e => setSearchVal(e.target.value)}
      />
      <datalist id='drugs'>
        {filteredDrugs.map((drug, index) => (
          <option value={drug} key={`drug-${drug}-${index}`} />
        ))}
      </datalist>
    </div>
  )
}

ReactDOM.createRoot(document.getElementById("root")).render(<App/>)

2. 检查并修复重复key

如果API返回的term有重复值,React的key冲突会加重渲染异常,给key加上索引兜底:

<option value={i} key={`drug-${i}-${index}`} />

3. 避免全量渲染

不要尝试一次性渲染3万+<option>,哪怕优化React渲染逻辑,浏览器也会因为DOM节点过多出现假死,搜索过滤才是合理的做法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 04:18:12