我正在使用其API创建一个Spotify应用程序。我想要 4 个视图(如"/"、"现在播放"、"收藏艺术家"、"收藏歌曲"(。
我需要setAccessToken
在每个新页面中使用getMyCurrentPlaybackState()
等功能,对吧?Idk 如果我需要在每个将使用getMyCurrentPlaybackState()
等功能的容器中if(params.access_token){spotifyWebApi.setAccessToken(params.access_token)}
.我正在考虑创建一个Spotify.jsx容器来处理Spotify对象的存储(该对象用于令牌和使用spotify函数的每个容器中(。但是有了这个 Spotify.jsx,我也不知道这是否是一种好方法,也不知道如何将其所需的spotifyWebApi
常量connect
到每个容器文件和令牌文件。
为了更好地理解我的想法:我会创建一个具有getHashParams()
的Token.jsx和一个具有getNowPlaying()
的Playing.jsx。每个人都需要spotifyWebApi
常量。
import React, { Component } from 'react';
import Spotify from 'spotify-web-api-js';
const spotifyWebApi = new Spotify();
class App extends Component {
constructor(){
super();
const params = this.getHashParams();
this.state = {
loggedIn: params.access_token ? true : false,
nowPlaying: {
name: 'Not Checked',
image: ''
}
}
if (params.access_token){
spotifyWebApi.setAccessToken(params.access_token)
}
}
getHashParams() {
var hashParams = {};
var e, r = /([^&;=]+)=?([^&;]*)/g,
q = window.location.hash.substring(1);
while ( e = r.exec(q)) {
hashParams[e[1]] = decodeURIComponent(e[2]);
}
return hashParams;
}
getNowPlaying(){
spotifyWebApi.getMyCurrentPlaybackState()
.then((response) => {
this.setState({
nowPlaying: {
name: response.item.name,
image: response.item.album.images[0].url
}
})
})
}
}
你的标题提到了 Redux,但我没有看到你的代码使用它。使用 Redux,您可以获取access_token,然后将其存储在状态中。这将允许您在任何 Redux 连接的组件中使用它。
此外,使用 Redux,您可以使用 ReduxThunk(或类似(中间件,该中间件允许您使用 Redux 操作来调用 API。因此,您只需将不同的 API 调用编写为 Redux 操作,这将允许您从任何组件调用它们,并将结果添加到您的 Redux 存储中(同样,可以在任何 Redux 连接的组件中使用(。
因此,例如,您的getNowPlaying()
函数可能是如下所示的操作:
function getNowPlaying() {
return function (dispatch, getState) {
// get the token and init the api
const access_token = getState().spotify.access_token
spotifyWebApi.setAccessToken(access_token)
return spotifyWebApi.getMyCurrentPlaybackState().then((response) => {
dispatch({
type: 'SET_NOW_PLAYING',
name: response.item.name,
image: response.item.album.images[0].url
})
})
}
}
注意:您需要为"spotify"(或您想要构建商店的方式(配置Redux缩减器来存储所需的数据。
因此,您可以从任何组件调用getNowPlaying((。它将结果存储在 redux 存储中,您也可以从任何连接的组件使用它。在操作中需要时,您可以使用相同的技术从商店获取access_token。
或者,如果你不想使用 Redux,你可以使用 React 的上下文功能为所有子组件提供上下文值。您可以使用设置中每个组件所需的令牌执行此操作。但在我看来,Redux 是你更好的选择。
与其将此 const 传递给其他组件,我会创建一个SpotifyUtils.jsx
并在其中声明 const。在这个帮助程序中,我将导出函数,以便其他组件可以使用它们。 例如:
import Spotify from 'spotify-web-api-js';
const spotifyWebApi = new Spotify();
let token = null
export function isLoggedIn() {
return !!token
}
export function setAccessToke(_token) {
token = _token;
spotifyWebApi.setAccessToken(_token);
}
export function getNowPlaying(){
return spotifyWebApi.getMyCurrentPlaybackState()
.then((response) => {
return {
name: response.item.name,
image: response.item.album.images[0].url
}
})
}
因此,在组件中您可以像这样使用它们:
import React, { Component } from 'react';
import {
isLoggedIn,
setAccessToken,
getNowPlaying,
} from 'helpers/SpotifyUtils'
class App extends Component {
constructor(){
super();
this.state = {
loggedIn: isLoggedIn(),
nowPlaying: {
name: 'Not Checked',
image: ''
}
}
getHashParams() {
var hashParams = {};
var e, r = /([^&;=]+)=?([^&;]*)/g,
q = window.location.hash.substring(1);
while ( e = r.exec(q)) {
hashParams[e[1]] = decodeURIComponent(e[2]);
}
return hashParams;
}
componentDidMount() {
if (!this.state.loggedIn) {
const params = this.getHashParams();
if (params.access_token) {
setAccessToken(params.access_token)
getNowPlaying()
.then(nowPlaying => this.setState({ nowPlaying }))
}
}
}
}
这将使您的spotifyWebApi const能够在您导入帮助程序函数的任何组件中重用。我特别喜欢这种模式,它以通用方式创建utils
或helpers
,以便您可以轻松地重用代码。此外,如果 spotify Web API 发布重大更改,您的重构将更容易,因为您只需要重构SpotifyUtils.jsx
文件,因为它将是唯一使用import Spotify from 'spotify-web-api-js'
的文件