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

React中Ajax请求出现Uncaught (in promise) TypeError问题求助

问题分析与解决方案

你遇到的Uncaught (in promise) TypeError: Cannot read property of undefined错误,核心原因是Promise的then回调里的this指向不对——你用了普通函数作为then的回调,这个函数里的this默认绑定的是全局对象(浏览器里是window),而不是你的React组件实例,所以自然找不到this.showBattersData方法。

第一步:修复this指向问题

有三种简单的方式可以解决这个问题:

1. 使用箭头函数(推荐)

箭头函数会继承外层作用域的this,也就是你的组件实例:

battersDataFetchReq() {
  fetchFactory('./assets/some.json', 'GET')
  .then((data) => { // 这里改成箭头函数
    this.showBattersData(data);
  })
}

2. 提前保存this到变量

在then之前把组件的this存到一个变量里,比如self,然后在回调里用这个变量:

battersDataFetchReq() {
  const self = this; // 保存组件的this
  fetchFactory('./assets/some.json', 'GET')
  .then(function(data) {
    self.showBattersData(data); // 用self代替this
  })
}

3. 用bind绑定this到回调函数

直接给回调函数绑定组件的this:

battersDataFetchReq() {
  fetchFactory('./assets/some.json', 'GET')
  .then(function(data) {
    this.showBattersData(data);
  }.bind(this)) // 绑定组件的this
}

第二步:优化React数据管理(重要)

你的代码里用了全局变量rowdata和batters来存储数据,这在React里是不推荐的——React不会监听全局变量的变化,就算你成功获取到数据,页面也不会自动更新渲染表格。正确的做法是用组件的state来管理数据:

修改后的完整代码:

import React, {Component} from 'react'
import { fetchFactory } from '../Fetch/fetchFactory'

export class Body extends React.Component {
  constructor(props) {
    super(props);
    this.battersDataFetchReq = this.battersDataFetchReq.bind(this);
    this.showBattersData = this.showBattersData.bind(this);
    // 初始化state存储batters数据
    this.state = {
      batters: []
    };
    this.battersDataFetchReq();
  }

  battersDataFetchReq() {
    fetchFactory('./assets/some.json', 'GET')
    .then((data) => { // 用箭头函数解决this问题
      this.showBattersData(data);
    })
    // 别忘了加catch处理请求错误!
    .catch(err => console.error('请求失败:', err))
  }

  showBattersData(res) {
    console.log("inside showBattersData:: ", res);
    // 更新state,React会自动触发重新渲染
    this.setState({
      batters: res.batters.batter
    });
  }

  render() {
    const { batters } = this.state;
    return (
      <div>
        <table id="batters" name="batters" className="table table-bordered table-hover">
          <caption>List of batters</caption>
          <thead>
            <tr>
              <th>#</th>
              <th>Id</th>
              <th>Type</th>
            </tr>
          </thead>
          <tbody id="batters_body">
            {/* 用map动态生成表格行,注意加key */}
            {batters.map((batter, index) => (
              <tr key={batter.id}>
                <td>{index + 1}</td>
                <td>{batter.id}</td>
                <td>{batter.type}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    );
  }
}

额外注意点:

  • React里HTML的class属性要写成className,因为class是JavaScript的关键字;
  • 用map渲染列表时,必须给每个元素加唯一的key属性(这里用batter.id是最佳选择);
  • 永远不要忘记给Promise加catch处理请求错误,避免未捕获的Promise错误;
  • 不要用拼接HTML字符串的方式生成DOM,React推荐用JSX语法,更安全也更易维护。

内容的提问来源于stack exchange,提问作者Nakul Nagariya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:16:08