React前端搜索结果可获取但无法在页面展示(附代码)
问题解决:搜索结果无法在页面展示
核心问题分析
- 搜索接口返回结果后,未将数据更新到React状态中,页面无法触发重新渲染
useEffect依赖userData导致组件挂载后无限重复请求初始数据,会覆盖搜索结果- 状态初始值类型不匹配(空字符串 vs 需要数组),可能引发渲染错误
具体修改点
修正状态初始值
将userData的初始值从空字符串改为空数组,确保后续map操作正常执行:const [userData, setUserData] = useState([]);修复useEffect无限循环
移除useEffect的userData依赖,改为空数组,让初始数据只在组件挂载时加载一次:useEffect(() => { fetchUserData(); }, []);更新搜索结果到状态
在searchHandle函数中,拿到后端返回的搜索结果后,调用setUserData更新状态,触发页面渲染:const searchHandle = async (event) => { let key = event.target.value; await axios .get(`http://localhost:5500/search/${key}`) .then((response) => { // 根据后端返回结构调整,这里假设和/getTodo一致返回{users: [...]} setUserData(response.data.users); }) .catch((err) => { console.log(err); }); };
修改后的完整代码
import React, { useEffect, useState } from "react"; import axios from "axios"; const UserList = () => { const [userData, setUserData] = useState([]); const fetchUserData = async () => { const resp = await axios.get("/getTodo"); console.log(resp); //if no user is there please dont set any value if (resp.data.users.length > 0) { setUserData(resp.data.users); } }; useEffect(() => { fetchUserData(); }, []); ///edit const handleEdit = async (user) => { var edittodo = `${user.todo}`; var edittask = `${user.task}`; const userTodo = prompt("Enter your Name", edittodo); const userTask = prompt("Enter your Email", edittask); if (!userTodo || !userTask) { alert("please Enter Todo and Task Both"); } else { const resp = await axios.put(`/editTodo/${user._id}`, { todo: userTodo, task: userTask, }); console.log(resp); // 编辑后重新获取数据,更新页面 fetchUserData(); } }; //Delete const handleDelete = async (userId) => { const resp = await axios.delete(`/deleteTodo/${userId}`); console.log(resp); // 删除后重新获取数据,更新页面 fetchUserData(); }; const searchHandle = async (event) => { let key = event.target.value; console.log(key) await axios .get(`http://localhost:5500/search/${key}`) .then((response) => { console.log(response.data); // 更新搜索结果到状态 setUserData(response.data.users); }) .catch((err) => { console.log(err); }); }; return ( <div> <form> <input type="text" className="search-box" placeholder="Search Todo" onChange={searchHandle} /> </form> <section className="text-gray-600 body-font"> <div className="container px-5 py-24 mx-auto"> <div className="flex flex-col text-center w-full mb-8"> <h1 className="sm:text-4xl text-3xl font-medium title-font mb-2 text-gray-900"> All Users </h1> </div> <div className="lg:w-2/3 w-full mx-auto overflow-auto"> <table className="table-auto w-full text-left whitespace-no-wrap"> <thead> <tr> <th className="px-4 py-3 title-font tracking-wider font-medium text-gray-900 text-sm bg-gray-100 rounded-tl rounded-bl"> Todo </th> <th className="px-4 py-3 title-font tracking-wider font-medium text-gray-900 text-sm bg-gray-100"> Task </th> <th className="px-4 py-3 title-font tracking-wider font-medium text-gray-900 text-sm bg-gray-100"> Edit </th> <th className="px-4 py-3 title-font tracking-wider font-medium text-gray-900 text-sm bg-gray-100"> Delete </th> </tr> </thead> <tbody> {userData.map((user, index) => ( <tr key={index}> <td className="px-4 py-3">{user.todo}</td> <td className="px-4 py-3">{user.task}</td> <td className="px-4 py-3"> <button className="hover:text-green-500" onClick={() => handleEdit(user)} > Edit </button> </td> <td className="px-4 py-3 text-lg text-gray-900"> <button className="hover:text-red-500" onClick={() => handleDelete(user._id)} > Delete </button> </td> </tr> ))} </tbody> </table> </div> </div> </section> </div> ); }; export default UserList;
额外优化说明
- 在
handleEdit和handleDelete操作后,调用fetchUserData()刷新页面数据,确保操作后列表实时更新 - 若搜索频率过高,可添加防抖函数减少不必要的请求,比如:
const debounce = (func, delay) => { let timeoutId; return (...args) => { clearTimeout(timeoutId); timeoutId = setTimeout(() => func.apply(this, args), delay); }; }; const debouncedSearch = debounce(searchHandle, 300); // 然后input的onChange改为onChange={debouncedSearch}
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

