Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/459.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我必须单击按钮两次,才能在React中正确渲染状态_Javascript_Reactjs - Fatal编程技术网

Javascript 我必须单击按钮两次,才能在React中正确渲染状态

Javascript 我必须单击按钮两次,才能在React中正确渲染状态,javascript,reactjs,Javascript,Reactjs,我正在使用React,我有一个按钮,用来设置状态 <button class="button" onClick={this.setRecommendations}> Log Into Spotify </button> 它会更新此状态建议:[],因此,当我单击按钮时,我会等待一段时间,但什么也不会发生,但可以肯定的是,无论我再次单击按钮时等待多长时间,结果都会开始显示 我知道setState是异步的,但这段代码模拟了一个类似的函数,它只需单击一下

我正在使用React,我有一个按钮,用来设置状态

<button class="button" onClick={this.setRecommendations}>
            Log Into Spotify
</button>
它会更新此状态
建议:[],
因此,当我单击按钮时,我会等待一段时间,但什么也不会发生,但可以肯定的是,无论我再次单击按钮时等待多长时间,结果都会开始显示

我知道setState是异步的,但这段代码模拟了一个类似的函数,它只需单击一下就可以更即时地显示结果,我能做些什么让它只需单击一下就可以工作吗

*******更新更多代码*******

这是我的应用程序

  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.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});
    });
  }

  setRecommendations(){
    recommendations().then(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() {
    //this.recommendations()
    return (
      <div>
        <h1>Spotify Recommendations</h1>
        <div className="App">
          <button class="button" onClick={this.setRecommendations}>
            Log Into Spotify
          </button>
          <Graphs data={this.state.album_count} margin={this.state.topAlbums} />
          <div className="Graphs">
            <Graphs data={this.state.artist_count} margin={this.state.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>
    );
  }
}

问题是在调用
窗口之后需要再次调用
getAccessToken()
。调用location
。决定在
窗口之后的else块中调用
getAccessToken()
。location
应该足够了,从而解决了这个问题。

问题是
getAccessToken()
需要在
窗口之后再次调用。location
被调用。决定在
窗口之后的else块中调用
getAccessToken()
。location
应该足够了,从而解决了这个问题。

添加更多关于如何在UI中使用
状态的上下文。你的
setRecommensions()
函数本身没有什么可疑之处。你应该在组件中添加你正在使用的所有代码,这样会更容易知道错误所在。我添加了更多的代码,如果你还想看什么,请告诉我。我承认SetRecommensions调用的函数有点长,可能需要一段时间,但奇怪的是,我单击login,然后登录并等待,无论等待多长时间,直到第二次单击都不会显示任何内容。您可以将方法声明更改为
search=(term)=>{…}
,而不是使用bind。这将方法附加到实例而不是原型,并且与构造函数中的绑定具有相同的效果?因为搜索是一个我不再真正使用的遗留函数,所以我忘了删除它。添加更多关于如何在UI中使用
state
的上下文。你的
setRecommensions()
函数本身没有什么可疑之处。你应该在组件中添加你正在使用的所有代码,这样会更容易知道错误所在。我添加了更多的代码,如果你还想看什么,请告诉我。我承认SetRecommensions调用的函数有点长,可能需要一段时间,但奇怪的是,我单击login,然后登录并等待,无论等待多长时间,直到第二次单击都不会显示任何内容。您可以将方法声明更改为
search=(term)=>{…}
,而不是使用bind。这将方法附加到实例而不是原型,并且与构造函数中的绑定具有相同的效果?因为搜索是一个我不再真正使用的遗留函数,所以我忘了删除它。
  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.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});
    });
  }

  setRecommendations(){
    recommendations().then(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() {
    //this.recommendations()
    return (
      <div>
        <h1>Spotify Recommendations</h1>
        <div className="App">
          <button class="button" onClick={this.setRecommendations}>
            Log Into Spotify
          </button>
          <Graphs data={this.state.album_count} margin={this.state.topAlbums} />
          <div className="Graphs">
            <Graphs data={this.state.artist_count} margin={this.state.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>
    );
  }
}
<RecommendationResults recommendationResults={this.state.recommendations}
                           onAdd={this.addTrack} />
class RecommendationResults extends React.Component {
  render() {
    return (
      <div className="RecommendationResults">
        <h2>Recommendations</h2>
        <TrackList tracks={this.props.recommendationResults} onAdd={this.props.onAdd} />
      </div>
    );
  }
}
class TrackList extends React.Component {
  render() {
    return (
      <div className="TrackList">
        {
          this.props.tracks.map(track => {
            return <Track track={track}
                          key={track.id}
                          onAdd={this.props.onAdd}
                          isRemoval={this.props.isRemoval}
                          onRemove={this.props.onRemove} />
          })
        }
      </div>
    );
  }
}
//get recommendations based off song history
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;
    }
  },