结构:
ApiService.js
components/
TrackComponent.jsx
TrackComponent.jsx
我在render()
的React中有此表单,它触发了一个事件,该事件撞到了一个端点:
<form onSubmit={ (event) => this.handleEditPlaylist(event) }>
<div className="field">
<input
name="artist"
className="input is-dark is-large"
type="text"
/>
</div>
</form>
句柄功能:
handleEditPlaylist(event) {
event.preventDefault();
const formType = this.props.formType
var headers = {
'Content-Type': 'application/json',
Authorization: `Bearer ${window.localStorage.authToken}`
}
const {userId} = this.props
const data = {
value: this.state.formData.value,
spotify_token: this.props.spotifyToken
};
const url = `${process.env.REACT_APP_WEB_SERVICE_URL}/handle_edit_playlist/${this.state.artist}/${userId}`;
axios.post(url, data, {headers: headers})
.then((res) => {
console.log(data);
if(data){this.clearForm();}
})
.catch((err) => {
});
axios.get(url, {
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${window.localStorage.authToken}`
}
}).then((res) => {
console.log(res.data);
this.setState({
seeds: res.data.data[0].seeds,
artist: res.data.data[0].artist,
})
})
};
这有效。
组件内部的API实例
现在,我必须在上面的组件中实例化此axios
拦截器,以便处理具有两个端点的访问令牌。
import Axios from 'axios';
class ApiService {
constructor() {
this.axios = Axios.create();
this.axios.interceptors.response.use(null, this.authInterceptor.bind(this));
this.get = this.axios.get.bind(this.axios);
this.post = this.axios.post.bind(this.axios);
}
async authorize() {
console.log('Async in authorize')
const { accessToken } = await this.axios.post('/get_token/1', {});
this.setAccessToken(accessToken);
return accessToken; // return it to the component that invoked it to store in some state
}
async getTrack(userId, spotifyToken, artist) { // <---------------------------
console.log('getAroma in ApiService', userId, spotifyToken, artist)
return this.axios.get(
`${process.env.REACT_APP_WEB_SERVICE_URL}/get-tracks/${artist}/${userId}/${spotifyToken}`
);
}
async updateAccessToken(userId) {
const { accessToken } = await this.axios.post(`/refresh-token/1`, {});
this.setAccessToken(accessToken);
}
(...)
export const apiService = new ApiService(); // this is a single instance of the service, each import of this file will get it
我也希望上面有相同的onSubmit
事件触发拦截器实例化调用。我可以这样:
import {apiService} from '../ApiService';
async getTrack(event) {
if (this.props.isAuthenticated) {
const {userId, spotifyToken} = this.props;
const {artist} = this.state.artist
const aromaticTracks = await apiService.getTracks(userId, spotifyToken, artist);
this.setState({newTracks});
} else {
this.setState({newTracks: []});
}
}
如果我在提交表单后立即在handleEditPlaylist
中插入此异步getTrack,就像这样:
(...)
axios.post(url, data, {headers: headers})
.then((res) => {
this.getTrack(); // <----------- HERE
console.log(data);
if(data){this.clearForm();}
})
(...)
我在async getTrack
console.log('getTrack in ApiService', userId, spotifyToken, artist)
中收到表单提交值(艺术家)的“未定义”,但在右下方打印了在console.log(data)
中提交的值。. < / p>
如何正确处理此拦截器onSubmit
?
答案 0 :(得分:1)
代码中的唯一问题是因为您试图从已经访问的状态中破坏一个值
async getTrack(event) {
if (this.props.isAuthenticated) {
const {userId, spotifyToken} = this.props;
const {artist} = this.state; // this needs to be this.state and not this.state.artist
const aromaticTracks = await apiService.getTracks(userId, spotifyToken, artist);
this.setState({newTracks});
} else {
this.setState({newTracks: []});
}
}
destructuring
赋值语法是一个JavaScript表达式,可以将数组中的值或对象中的属性解压缩为不同的变量。
阅读object destructuring
的文档