React.js点击按钮触发API Fetch请求的实现与问题修复
代码修复说明
核心问题
- 搜索请求逻辑写在空依赖的useEffect中,仅页面首次加载时触发一次,未和搜索按钮绑定
- 混用async/await和.then异步写法,try/catch无法捕获fetch请求抛出的异常
- 请求返回数据后仅做打印,未调用setItemList更新状态
- 未做必填参数(商品名称)校验,未处理年份未选择的可选参数场景
修复后完整代码
import { useState, useEffect } from 'react'; const App = () => { const [YearList, setYearsData] = useState([]); const [NamesList, setNameData] = useState([]); const [itemList, setItemList] = useState([]); const [year, setYear] = useState("") const [searchQuery, setSearchQuery] = useState("") // 加载年份下拉数据 useEffect(() => { const fetchYearData = async () => { try { const response = await fetch("http://localhost:56384/api/YearList") const itemData = await response.json() setYearsData(itemData) } catch(error) { console.log("获取年份列表失败", error); } }; fetchYearData() }, []); // 加载商品名称列表 useEffect(() => { const fetchNameData = async () => { try { const response = await fetch("http://localhost:56384/api/NameList") const itemData = await response.json() setNameData(itemData) } catch(error) { console.log("获取商品名称列表失败", error); } }; fetchNameData() }, []); // 年份选择回调 const handleYearChange = (e) => { setYear(e.target.value) } // 搜索输入回调 const handleSearchChange = (e) => { setSearchQuery(e.target.value) } // 搜索按钮点击回调 const handleSearch = async () => { // 校验必填参数 if (!searchQuery.trim()) { alert("请输入商品名称") return } // 拼接参数 const params = new URLSearchParams() params.append('searchText', searchQuery.trim()) // 仅选择年份后才加参数 if (year && year !== "-- Select year --") { params.append('year', year) } try { const response = await fetch(`http://localhost:56384/api/RecallSearch?${params.toString()}`) const itemData = await response.json() // 更新结果数组 setItemList(itemData) console.log("搜索结果", itemData) } catch(error) { console.log("搜索请求失败", error); } } return ( <div className="App"> <TitleCard /> <input type="text" value={searchQuery} onChange={handleSearchChange} placeholder='Search Amazon Items' /> <select onChange={handleYearChange} value={year}> <option value="-- Select year --"> -- Select a Year -- </option> {YearList.map((year) => <option key={year} value={year}>{year}</option>)} </select> {/* 绑定搜索点击事件 */} <button onClick={handleSearch}>Search</button> </div> ); } export default App;
修改点说明
- 删除了原有的空依赖搜索请求useEffect,新增handleSearch函数绑定到搜索按钮onClick事件,只有点击按钮才触发查询
- 统一所有异步请求为async/await写法,异常捕获逻辑生效
- 新增商品名称必填校验,空输入时拦截请求
- 用URLSearchParams拼接参数,未选择年份时不携带year参数,符合可选参数要求
- 请求成功后调用setItemList更新状态数组,可直接用于后续列表渲染
- 给select组件补充value属性,实现双向绑定避免状态和视图不一致
内容的提问来源于stack exchange,提问作者Jesse Ly
相关产品推荐
相关产品推荐

