You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 12:27:25