React类组件获取地理坐标报TypeError属性未定义错误
报错根因
你遇到的错误核心是**this上下文丢失**,叠加Promise逻辑写法错误、类属性重复声明问题共同导致,其中直接触发报错的是地理定位回调的this指向错误。原生JS环境下你大概率是把坐标变量定义在全局作用域,不需要依赖this访问,所以没有暴露问题,迁移到类组件后实例属性都挂载在组件实例的this上,this指向错误就会直接读不到属性。
具体错误点
- 地理定位API的回调使用普通
function声明:普通函数的this由调用方决定,navigator.geolocation.getCurrentPosition执行回调时不会绑定组件实例作为this,严格模式下回调内的this为undefined,执行this.CurrentPosition[0] = ...时直接触发你看到的类型错误。 secondDo方法内Promise逻辑错误:resolve()被写在fetch链式调用的外层,不管接口请求有没有完成都会直接返回,await不会等待接口响应完成,后续读取接口数据时会拿到undefined。- 类顶部重复声明
CurrentPosition、data_set类字段:会覆盖constructor里初始化的[0,0]默认值,把属性重置为undefined,属于冗余错误写法。
修复后完整代码
class Data_item extends React.Component{ constructor(props){ super(props) // 实例属性统一在constructor初始化,不需要额外在类顶部重复声明 this.CurrentPosition = [0,0] this.data_set = null this.state = { weather: props, forecastData: null } } firstDo(){ return new Promise((resolve, reject)=>{ // 改用箭头函数回调,继承外层组件实例的this指向 navigator.geolocation.getCurrentPosition((position) => { this.CurrentPosition[0] = position.coords.latitude; this.CurrentPosition[1] = position.coords.longitude; resolve() }, (err) => { // 补全定位失败的错误捕获 reject(err) }) }) } secondDo(){ return new Promise((resolve,reject)=>{ fetch(`https://api.open-meteo.com/v1/forecast?latitude=${this.CurrentPosition[0]}&longitude=${this.CurrentPosition[1]}&daily=weathercode,temperature_2m_max,temperature_2m_min,apparent_temperature_max,apparent_temperature_min,sunrise,sunset,precipitation_sum,precipitation_hours,windspeed_10m_max,windgusts_10m_max,winddirection_10m_dominant,shortwave_radiation_sum,et0_fao_evapotranspiration&timezone=Europe%2FMoscow`) .then(response => response.json()) .then(response => { this.data_set = response // 拿到数据后更新state触发组件重渲染 this.setState({forecastData: response}) resolve(response) }) .catch(err => { console.error(err) reject(err) }); }) } async resulting_(){ try { await this.firstDo() await this.secondDo() } catch (err) { console.error('流程执行失败:', err) } } componentDidMount(){ this.resulting_() } render() { // 在此处编写你的天气数据渲染逻辑即可 return <div className="weather-card"></div> } }
注意事项
- 类组件中如果需要在回调内访问组件实例的属性/方法,优先使用箭头函数,箭头函数没有自己的this,会继承外层作用域的this指向,也就是组件实例,避免上下文丢失;如果要用普通function,需要手动调用
.bind(this)绑定上下文。 - Promise的
resolve/reject必须放在异步操作的回调内部,确保异步操作完成后再改变Promise状态,否则await会失去等待效果。 - 类属性不要重复声明,已经在constructor中初始化的属性不需要再在类顶部单独声明,避免初始值被覆盖。
内容的提问来源于stack exchange,提问作者raxenov1
相关产品推荐
相关产品推荐

