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