React:调用API获取数据填充select下拉选项功能异常排查
问题描述
- 需求:调用API发起GET请求获取返回值,填充select下拉选项菜单
- 现状:已实现根据用户输入的地点编码请求接口,可成功返回对应值列表,下拉菜单UI也已开发完成,但功能无法正常生效,判断为
state/setState使用错误导致 - 预期效果:用户在文本输入框输入
1449时,下拉选项展示PAAF、EXLA两个选项

接口GET请求返回字符串数组格式的承运商列表,数据结构如下:
[ "PAAF", "EXLA" ]
原有问题代码:
import React from 'react'; import axios from 'axios'; export default class FetchCarrierList extends React.Component { state = { carriers: [] } render() { function loadCarriers(url) { axios({ method: "get", url: url }).then((response) => { let relCarriers = response.data; console.log(relCarriers); this.setState({relCarriers}); }).catch((response) => { console.log(response); alert('Error communicating with server'); }); } function getData(val) { let location = val.target.value; let baseUrl = "http://localhost:6012/myAPI/carrier/getCarriersByLocation/" + location; if (location.length === 4) { loadCarriers(baseUrl); } } return <div className="editPro"> <h1>Edit Pro Numbers</h1> <div id="carrierSelection"> <input type="text" id="locationEntry" onChange={getData}></input> <select id="carrierDropDown"> <option selected disabled>Select A Carrier</option> {this.state.carriers.map(option => <option key={option} value={option}>{option}</option>)} </select> </div> </div> } }
错误原因
代码共有3处核心问题:
loadCarriers、getData两个方法直接定义在render函数内部,普通函数的this不指向组件实例,调用this.setState时会直接抛出找不到方法的错误setState更新的字段名错误:state中定义的存储承运商列表的字段是carriers,但代码中写的是this.setState({relCarriers}),即使setState正常执行,也不会更新下拉框绑定的this.state.carriers字段onChange事件直接绑定render内部定义的普通函数,触发时函数内上下文丢失,无法正确调用组件实例上的方法
修复后代码
import React from 'react'; import axios from 'axios'; export default class FetchCarrierList extends React.Component { state = { carriers: [] } // 方法定义到类实例上,用箭头函数自动绑定组件this上下文 loadCarriers = (url) => { axios({ method: "get", url: url }).then((response) => { const carriers = response.data; console.log(carriers); // 修正setState字段名,和state中定义的carriers对应 this.setState({ carriers }); }).catch((err) => { console.log(err); alert('Error communicating with server'); }); } getData = (val) => { const location = val.target.value; const baseUrl = `http://localhost:6012/myAPI/carrier/getCarriersByLocation/${location}`; if (location.length === 4) { this.loadCarriers(baseUrl); } } render() { return <div className="editPro"> <h1>Edit Pro Numbers</h1> <div id="carrierSelection"> <input type="text" id="locationEntry" onChange={this.getData}></input> <select id="carrierDropDown"> <option selected disabled>Select A Carrier</option> {this.state.carriers.map(option => <option key={option} value={option}>{option}</option>)} </select> </div> </div> } }
内容的提问来源于stack exchange,提问作者Austin
相关产品推荐
相关产品推荐

