React搜索组件输入字符后报错map is not a function,页面空白求助
React用户名搜索功能:
map is not a function错误解决 错误原因
- 后端返回数据非数组:初始
data状态是数组,但请求后端后,返回的res.json()可能是对象(比如常见的{ code: 200, data: [...] }结构),或是错误信息对象,此时setData(data)会把data变成非数组类型,调用map时就会抛出map is not a function错误。 - 未处理请求异常:如果请求失败(如后端服务异常、跨域问题),
res.json()可能抛出错误,或返回非预期格式数据,导致data状态异常。 - 额外问题:map未返回JSX:即使
data是数组,当前代码中map的箭头函数没有返回JSX元素,也会导致搜索建议无法渲染,但这不是页面空白的直接触发原因。
解决办法
1. 确认并适配后端返回格式
先在onChange中打印返回数据,确认结构:
const responseData = await res.json(); console.log(responseData); // 查看后端实际返回内容
如果后端返回的是包含数组的对象(比如{ data: [...] }),则调整setData的参数:
setData(responseData.data || []);
如果后端直接返回数组,就用setData(responseData)。
2. 添加请求错误捕获
用try/catch包裹请求逻辑,避免请求失败导致状态异常:
const onChange = async (e) => { setValue(e.target.value); try { const res = await fetch('http://localhost:5000/api/users'); // 检查请求是否成功 if (!res.ok) throw new Error(`请求错误:${res.status}`); const responseData = await res.json(); // 确保设置的数据是数组,兜底为空数组 setData(Array.isArray(responseData) ? responseData : responseData.data || []); } catch (err) { console.error(err); setData([]); // 错误时重置为空数组,避免map报错 } };
3. 修正map的JSX返回逻辑
当前map回调中没有返回元素,需要改为隐式返回(用括号包裹JSX)或显式return:
<div className="dropdown-content"> { data.map((item) => ( <div key={item.id}> {item.name} </div> )) } </div>
完整修正后的组件代码
import { useState } from "react"; import { Button } from "@chakra-ui/react"; import "./search.css"; const Search = () => { const [value, setValue] = useState(''); const [data, setData] = useState([]); const onChange = async (e) => { setValue(e.target.value); try { const res = await fetch('http://localhost:5000/api/users'); if (!res.ok) throw new Error(`请求错误:${res.status}`); const responseData = await res.json(); setData(Array.isArray(responseData) ? responseData : responseData.data || []); } catch (err) { console.error(err); setData([]); } }; return ( <div className="search"> <div> <input type="text" value={value} className="search" placeholder="looking for someone?..." onChange={onChange} /> <Button>Search</Button> </div> <div className="dropdown-content"> { data.map((item) => ( <div key={item.id}> {item.name} </div> )) } </div> </div> ) } export default Search
内容的提问来源于stack exchange,提问作者Phoenix Phoenix
相关产品推荐
相关产品推荐

