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

ReactJS中作用域与OOP问题:函数调用时this未定义

Fixing "this is undefined" When Calling Functions in React with Spotify API

Hey there! Let's break down why you're hitting that Unhandled Rejection (TypeError): this is undefined error and get it fixed right away.

Why This Happens

The root issue comes down to how this works in JavaScript regular functions. When you pass a standard function() to the .then() method in your getPlaylists function, that callback creates its own this context—one that doesn't point to your React component instance. Since React runs in strict mode by default, this inner this ends up being undefined, so calling this.getPlaylistTracks() throws an error.

3 Simple Fixes

Let's walk through the most common solutions, starting with the cleanest modern approach:

1. Use Arrow Functions for the Promise Callback

Arrow functions don't create their own this—they inherit the this from the outer scope (your component instance). Just swap out the regular function for an arrow function in your .then():

getPlaylists() {
  spotifyApi.getUserPlaylists().then(
    (data) => { // Changed to arrow function here
      var playlistArray = [];
      for(let i = 0; i < data.items.length; i++) {
        var tracksURL = data.items[i].tracks.href.slice(37,59);
        var playlist = new PlaylistObj(data.items[i].name, data.items[i].tracks.total, tracksURL);
        this.getPlaylistTracks(tracksURL); // Now `this` correctly points to your component
        playlistArray[i] = playlist;
      }
      return playlistArray;
    },
    (err) => { // Optional: Swap this error callback to arrow function too
      console.error(err);
    }
  );
}

2. Bind this to the Callback Function

If you prefer sticking with regular functions, you can explicitly bind the component's this to the callback using .bind(this):

getPlaylists() {
  spotifyApi.getUserPlaylists().then(
    function (data) {
      var playlistArray = [];
      for(let i = 0; i < data.items.length; i++) {
        var tracksURL = data.items[i].tracks.href.slice(37,59);
        var playlist = new PlaylistObj(data.items[i].name, data.items[i].tracks.total, tracksURL);
        this.getPlaylistTracks(tracksURL);
        playlistArray[i] = playlist;
      }
      return playlistArray;
    }.bind(this), // Bind component's `this` to the callback
    function (err) {
      console.error(err);
    }
  );
}

3. Save this to a Variable Before the Promise

A reliable old-school trick is to store the component's this in a variable (like that) before entering the Promise chain, then use that variable inside the callback:

getPlaylists() {
  const that = this; // Save component's `this` to a variable
  spotifyApi.getUserPlaylists().then(
    function (data) {
      var playlistArray = [];
      for(let i = 0; i < data.items.length; i++) {
        var tracksURL = data.items[i].tracks.href.slice(37,59);
        var playlist = new PlaylistObj(data.items[i].name, data.items[i].tracks.total, tracksURL);
        that.getPlaylistTracks(tracksURL); // Use `that` instead of `this`
        playlistArray[i] = playlist;
      }
      return playlistArray;
    },
    function (err) {
      console.error(err);
    }
  );
}

Bonus: Prevent Future this Issues

To avoid similar problems elsewhere in your component, make sure your getPlaylists and getPlaylistTracks methods are bound to the component instance. Here are two easy ways:

Option A: Bind in the Constructor

constructor(props) {
  super(props);
  // Bind methods to component instance
  this.getPlaylists = this.getPlaylists.bind(this);
  this.getPlaylistTracks = this.getPlaylistTracks.bind(this);
}

Option B: Define Methods as Arrow Functions

This is a cleaner modern approach—arrow functions for class methods automatically bind this to the component:

// Define methods as arrow functions
getPlaylistTracks = (tracksURL) => {
  spotifyApi.getPlaylist(tracksURL).then(
    (data) => {
      console.log(data);
    },
    (err) => {
      console.error(err);
    }
  );
}

getPlaylists = () => {
  spotifyApi.getUserPlaylists().then(
    (data) => {
      var playlistArray = [];
      for(let i = 0; i < data.items.length; i++) {
        var tracksURL = data.items[i].tracks.href.slice(37,59);
        var playlist = new PlaylistObj(data.items[i].name, data.items[i].tracks.total, tracksURL);
        this.getPlaylistTracks(tracksURL);
        playlistArray[i] = playlist;
      }
      return playlistArray;
    },
    (err) => {
      console.error(err);
    }
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 15:27:40