React Autocomplete组件输入时数组重复添加数据的问题修复
修复React Autocomplete输入重复数据问题
问题描述
每次在TextField输入字符时都会触发getDatafromAPI调用接口,将返回的用户名添加到myOptions数组中。输入单个字符时数组有10个元素正常,但输入2个及以上字符时,数组会重复添加数据出现重复项。
问题根源
- 直接修改React状态数组:代码中使用
myOptions.push()直接修改原状态数组,违反了React状态不可变的原则,导致状态更新异常。 - 重复添加数据:每次调用API后,都在原数组基础上追加新数据,而不是替换原有数组,多次输入后自然会出现重复项。
修复方案
方案1:核心修复(替换状态数组)
不再修改原数组,而是从API返回的数据中生成新的选项数组,直接替换原有状态:
import React, { useState } from "react"; import { TextField } from "@mui/material"; import { Autocomplete } from "@mui/material"; const App = () => { const [myOptions, setMyOptions] = useState([]); const getDatafromAPI = () => { console.log("Getting data from API..."); fetch('https://jsonplaceholder.typicode.com/users/') .then((response) => response.json()) .then((res) => { // 从返回数据中提取用户名,生成全新数组 const newOptions = res.map(user => user.name); // 直接用新数组替换旧状态 setMyOptions(newOptions); console.log(newOptions); }); }; return ( <div style={{ marginLeft: '40%', marginTop: '60px' }}> <h3>Hello, This is my react search bar</h3> <Autocomplete style={{ width: 500 }} freeSolo autoComplete autoHighlight options={myOptions} renderInput={(params) => ( <TextField {...params} onChange={getDatafromAPI} variant='outlined' label='Search some things' /> )} /> </div> ); }; export default App;
方案2:添加防抖优化(可选,减少频繁请求)
如果希望避免用户输入过程中频繁调用API,可以添加防抖逻辑,等待用户停止输入一段时间后再发起请求:
import React, { useState, useCallback } from "react"; import { TextField } from "@mui/material"; import { Autocomplete } from "@mui/material"; const App = () => { const [myOptions, setMyOptions] = useState([]); let debounceTimer = null; const getDatafromAPI = useCallback(() => { // 清除之前的计时器,防止重复请求 if (debounceTimer) clearTimeout(debounceTimer); debounceTimer = setTimeout(() => { console.log("Getting data from API..."); fetch('https://jsonplaceholder.typicode.com/users/') .then((response) => response.json()) .then((res) => { const newOptions = res.map(user => user.name); setMyOptions(newOptions); console.log(newOptions); }); }, 300); // 设置300ms延迟,可根据需求调整 }, []); return ( <div style={{ marginLeft: '40%', marginTop: '60px' }}> <h3>Hello, This is my react search bar</h3> <Autocomplete style={{ width: 500 }} freeSolo autoComplete autoHighlight options={myOptions} renderInput={(params) => ( <TextField {...params} onChange={getDatafromAPI} variant='outlined' label='Search some things' /> )} /> </div> ); }; export default App;
修复说明
- 核心修复点:通过
res.map()生成新数组,用setMyOptions(newOptions)直接替换旧状态,彻底避免重复添加数据。 - 防抖优化:通过延迟执行API请求,减少不必要的网络请求,提升用户体验。
内容的提问来源于stack exchange,提问作者SM1L3_B0T
相关产品推荐
相关产品推荐

