如何在React中实现对应下拉框选中ID的动态HTTP GET端点请求
问题1解答
- 不建议将两个请求逻辑放在同一个useEffect中,二者的触发场景完全独立:
- 拉取id列表的逻辑仅需要在组件挂载时执行1次,依赖项为空数组即可
- 拉取对应location的逻辑需要在选中的id值发生变化时触发,依赖项应设置为选中的value值,拆分两个useEffect逻辑更清晰,也不会产生不必要的重复请求。
问题2解答
报错是因为初始状态下选中值为空,请求发送前没有做有效值校验,且下拉框没有绑定默认值,按以下规则修改即可解决:
- 给
select标签绑定value属性,和value状态关联,保证状态和视图一致 - 拉取到ids列表后,自动将第一个id设置为默认选中值,触发首次location查询
- 拉取location的useEffect中增加校验逻辑,仅当value为有效值时才发送请求,避免拼接undefined到请求地址
- 将
value的初始值改为空字符串而非空数组,符合下拉框选中值的类型要求
修正后完整代码
const request = axios.create({ baseURL: "https://veselka.maka-ars.com", timeout: 30000, }); const endpointIds = "/fiddle/getIds"; function Dropdown() { const [ids, setIds] = React.useState([]); const [location, setLocation] = React.useState(); // 初始值改为空字符串,符合单选项值类型 const [value, setValue] = React.useState(''); React.useEffect(() => { request.get(endpointIds).then((response) => { const loadedIds = []; for (const id of response.data.ids) { loadedIds.push({ id }); } setIds(loadedIds); // 拉取到id列表后默认选中第一个 if (loadedIds.length > 0) { setValue(loadedIds[0].id); } }); }, []); // 监听选中值变化,触发location查询 React.useEffect(() => { // 加校验,只有value有有效值时才发请求 if (!value) return; const endpointLocation = "fiddle/getLocation/" + value; request.get(endpointLocation).then((response) => { const loadedLocation = response.data.location; setLocation(loadedLocation); }); }, [value]); // 依赖项为选中的value const valueChangeHandler = (event) => { setValue(event.target.value); // 原来的全局event访问是错误的,移到事件回调内 console.log(event.target.value); }; const idsList = ids.map((id) => <option key={id.id} value={id.id}>{id.id}</option>); return ( <div> {/* 给select绑定value属性,关联状态 */} <select value={value} onChange={valueChangeHandler}>{idsList}</select> <p>{location}</p> </div> ); }
内容的提问来源于stack exchange,提问作者Trav
相关产品推荐
相关产品推荐

