React Native集成HERE API autocomplete输入3字符后无响应求助
问题排查与修复方案
核心问题定位
1. 服务端路由路径错误
你的Express服务中,API路由定义缺少开头的斜杠:
// 错误写法 app.get("api/search", async (req, res) => { ... }) // 正确写法 app.get("/api/search", async (req, res) => { ... })
没有斜杠会导致路由无法匹配,当输入第三个字符触发请求时,服务端返回404,前端无法获取数据,也就不会更新data状态,终端自然没有后续输出。
2. FlatList未渲染列表项
你在FlatList的renderItem中只写了空的Pressable,没有调用getItemText组件,所以即使拿到HERE API返回的数据,界面也不会显示任何结果:
// 错误写法 <FlatList data={data} renderItem={({ item, index }) => ( <Pressable onPress={() => alert("navigate passing" + JSON.stringify(item))}> </Pressable> )} /> // 正确写法 <FlatList data={data} renderItem={({ item, index }) => ( <Pressable onPress={() => alert("navigate passing" + JSON.stringify(item))}> {getItemText(item)} </Pressable> )} keyExtractor={(item) => item.id} // 必须添加keyExtractor,避免警告 />
3. 输入状态初始化异常
useState<string>()初始值为undefined,会导致TextInput的value属性异常,建议初始化为空字符串:
const [input, setInput] = useState<string>(""); const [data, setData] = useState<Location[]>([]);
4. 请求参数未编码与错误处理缺失
- 前端请求时,
location参数需要用encodeURIComponent编码,避免特殊字符(如空格)破坏URL结构:
let endpoint = `http://192.168.0.105:4000/api/search?location=${encodeURIComponent(text)}&limit=${5}`
- 服务端请求HERE API时,同样需要编码
q参数:
const endpoint = `https://autocomplete.search.hereapi.com/v1/autocomplete?apikey=${process.env.HERE_key}&lang=it-IT&limit=${req.query.limit}&q=${encodeURIComponent(req.query.location as string)}`;
- 前端fetch请求未判断响应状态,即使返回404/500也会尝试解析JSON,添加
res.ok判断:
const res = await fetch(endpoint); if (res.ok) { // 只有状态码200-299才处理 const data: Location[] = await res.json(); setData(data); // 即使data为空也更新,避免旧数据残留 } else { setData([]); }
5. 服务端错误处理优化
服务端catch块中可以打印错误信息,方便排查问题:
catch (error) { console.error("HERE API请求错误:", error); res.send([]); }
修复后关键代码片段
服务端index.ts修复后路由
app.get("/api/search", async (req, res) => { try { const locationQuery = req.query.location as string; const limit = req.query.limit as string; const endpoint = `https://autocomplete.search.hereapi.com/v1/autocomplete?apikey=${process.env.HERE_key}&lang=it-IT&limit=${limit}&q=${encodeURIComponent(locationQuery)}`; const { data } = await axios.get(endpoint); res.send(data || []); } catch (error) { console.error("请求HERE API失败:", error); res.send([]); } });
前端TabTwoScreen修复后onChangeText与FlatList
const onChangeText = async (text: string) => { setInput(text); if (text.length === 0) { return setData([]); } if (text.length > 2) { try { let endpoint = `http://192.168.0.105:4000/api/search?location=${encodeURIComponent(text)}&limit=${5}`; const res = await fetch(endpoint); if (res.ok) { const data: Location[] = await res.json(); setData(data); } else { setData([]); } } catch (error) { console.error("请求后端失败:", error); setData([]); } } console.log("get data"); }; // ... <FlatList data={data} renderItem={({ item }) => ( <Pressable onPress={() => alert("navigate passing" + JSON.stringify(item))}> {getItemText(item)} </Pressable> )} keyExtractor={(item) => item.id} />
内容的提问来源于stack exchange,提问作者Fabio
相关产品推荐
相关产品推荐

