javascript - onClick 在 React 中没有正确触发该函数

标签 javascript reactjs

所以我有这个按钮:

<button onClick={this.setRecommendations}>
   log into Spotify
</button>

调用此函数:

setRecommendations(){
    recommendations().then(recs => {
      this.setState({recommendations: recs});
    });
  }

调用此函数:

export async function recommendations(){
  const unique = await findUnique();
  const recommendations = [];
  for(var index = 0; index < unique.length; index++){
    var trackURI = (unique[index].uri).slice(14, (unique[index].uri).length);
    var rec = await Spotify.recommendations(trackURI, unique[index].pop);
    for(var i=0; i<rec.length; i++){
      recommendations.push(rec[i]);
    }
  }
  const uniqueRec = getUnique(recommendations);
  return await uniqueRec;
}

它调用另一个函数,而另一个函数最终要做的第一件事就是调用 getAccessToken:

getAccessToken() {
    if (accessToken) {
      return accessToken;
    }
    const accessTokenMatch = window.location.href.match(/access_token=([^&]*)/);
    const expiresInMatch = window.location.href.match(/expires_in=([^&]*)/);
    if (accessTokenMatch && expiresInMatch) {
      accessToken = accessTokenMatch[1];
      const expiresIn = Number(expiresInMatch[1]);
      window.setTimeout(() => accessToken = '', expiresIn * 1000);
      window.history.pushState('Access Token', null, '/'); // This clears the parameters, allowing us to grab a new access token when it expires.
      return accessToken;
    } else {
      const accessUrl = `https://accounts.spotify.com/authorize?client_id=${clientId}&response_type=token&scope=${scopes.join("%20")}&redirect_uri=${redirectUri}`;
      window.location = accessUrl;
    }
  },

这些功能最终可以工作,但您必须单击按钮两次。昨晚,我尝试放置一些 console.log() 来查看发生了什么,然后我意识到 this.setRecommendation 似乎没有被调用,直到第二次点击。但按钮仍然将您带到登录屏幕,因此不知何故它到达了 getAccessToken:

我什至尝试过:

setRecommendations(){
    console.log("you pushed the button");
    recommendations().then(recs => {
      this.setState({recommendations: recs});
    });
  }

并且“您按下按钮”在第二次单击之前仍然不会被控制台记录,但它会再次带您登录,因此我创建了第二个函数 login() 以及所有它所做的是调用 getAccessToken():

  login(){
    Spotify.getAccessToken();
  }

所以我有两个按钮,一个调用 this.login,另一个在我单击 this.login 时调用 this.setRecommendations,然后 this.setRecommendations 它按您的预期工作,很好地填充了组件。

但我仍然希望只需点击一下即可。我尝试过:

  <button onClick={() => {
                          this.login();
                          this.setRecommendations();}}>
          log into Spotify
          </button>

但这不起作用,它仍然调用 this.login() 并且似乎不会调用 this.setRecommendations() 直到再次单击。

这是我的应用程序组件

import React from 'react';
import './App.css';
import {Spotify, recommendations} from '../../utils/Spotify';
import RecommendationButton from '../RecommendationButton/RecommendationButton';
import Playlist from '../Playlist/Playlist';
import Graphs from '../Graphs/Graphs'
import RecommendationResults from '../RecommendationResults/RecommendationResults';


class App extends React.Component {
  //constructor
  constructor(props) {
    super(props);

    this.state = {
      searchResults: [],
      recommendations: [],
      playlistName: 'New Playlist',
      playlistTracks: [],
      topAlbums: ["Cats", "Wicked", "Heathers", "Charli", "Little Mermaind"],
      album_count: [10, 20, 25, 30, 35],
      topArtist: ["Dua Lipa", "Sierra Boggess", "Barrett Wilbert Reed", "Charli XCX", "Jessica Klean"],
      artist_count: [5, 10, 25, 35, 55],
      topGenre: ["classical", "broadway", "pop", "punk", "hip-hop"],
      genre_count: [50, 25, 5, 13, 7],
      popRange: ["0-20", "21-40", "41-60", "61-80", "81-100"],
      pop_count: [20, 40, 60, 40, 20]
    };
    this.search = this.search.bind(this);
    this.login = this.login.bind(this);
    this.setRecommendations = this.setRecommendations.bind(this);
    this.addTrack = this.addTrack.bind(this);
    this.removeTrack = this.removeTrack.bind(this);
    this.updatePlaylistName = this.updatePlaylistName.bind(this);
    this.savePlaylist = this.savePlaylist.bind(this);
  }

  search(term) {
    Spotify.search(term).then(searchResults => {
      this.setState({searchResults: searchResults});
    });
  }

  login(){
    Spotify.getAccessToken();
  }

  setRecommendations(){
    recommendations().then(recs => {
      console.log(recs);
      this.setState({recommendations: recs});
    });
  }

  //addTracks
  addTrack(track) {
    let tracks = this.state.playlistTracks;
    if (tracks.find(savedTrack => savedTrack.id === track.id)) {
      return;
    }

    tracks.push(track);
    this.setState({playlistTracks: tracks});
  }

  //removeTracks
  removeTrack(track) {
    let tracks = this.state.playlistTracks;
    tracks = tracks.filter(currentTrack => currentTrack.id !== track.id);

    this.setState({playlistTracks: tracks});
  }

  //updatePlaylistName
  updatePlaylistName(name) {
    this.setState({playlistName: name});
  }

  //savePlaylist
  savePlaylist() {
    const trackUris = this.state.playlistTracks.map(track => track.uri);
    Spotify.savePlaylist(this.state.playlistName, trackUris).then(() => {
      this.setState({
        playlistName: 'New Playlist',
        playlistTracks: []
      });
    });
  }

  //This what we will see
  render() {
    return (
      <div>
        <h1>Spotify Recommendations</h1>
        <div className="App">
          <button onClick={this.login}>
          log into Spotify
          </button>
          <RecommendationButton onPush={this.setRecommendations} />
          <Graphs data={this.state.album_count} margins={this.state.topAlbums} graphID={"topAlbums"} />
          <div className="Graphs">
            <Graphs data={this.state.artist_count} margins={this.state.topArtist} graphID={"topArtist"}/>
          </div>
          <p> below are some recommendations based on your listening history </p>
          <div className="App-playlist">
            <RecommendationResults recommendationResults={this.state.recommendations}
                           onAdd={this.addTrack} />

            <Playlist playlistName={this.state.playlistName}
                      playlistTracks={this.state.playlistTracks}
                      onNameChange={this.updatePlaylistName}
                      onRemove={this.removeTrack}
                      onSave={this.savePlaylist} />
          </div>
        </div>
      </div>
    );
  }
}


export default App;

最佳答案

您需要访问 token 才能获得推荐吗?

可能的情况是,第一次单击时,程序尚没有获取推荐所需的访问 token ,这就是为什么需要两次单击,因为在两次单击之间有一个暂停来获取访问 token 点击次数。这可能是由 getAccessToken 中的以下行引起的:

window.setTimeout(() => accessToken = '', expiresIn * 1000);

您可以尝试让 getAccessToken() 返回一个 promise ,其中解析值是访问 token 。然后在您的登录函数中调用 getAccessToken.then() setRecommendations

在 JSX 中,您只需 onClick={this.login}

关于javascript - onClick 在 React 中没有正确触发该函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59520730/

相关文章:

javascript - 幻灯片顶部的菜单故障

javascript - 获取 <div> 标签的值

reactjs - 如何在不导航到子组件的情况下发送值

django - 如何使用reactjs获取django url中url中的媒体图像

javascript - 如何调整 png 图像以适应 div?

JavaScript 数字每次 parseFloat toFixed 都没有正确添加

javascript - 哨兵程序无法运行

javascript - 为什么当我通过浏览器打开 html 页面时我的倒计时应用程序可以正常工作,但当我使用 http 服务器时却不能?

reactjs - React-native:在不同屏幕中删除 BackHandler

android - React native :Unable to resolve module Indeed, 这些文件都不存在: