與MobX反應(來自create-react-app)。使用axios進行異步後端API調用。重構打破初始狀態
此代碼有效。初始狀態(問題陣列)已填充,呈現此組件的網頁呈現來自狀態的初始內容。
import { observable, computed, autorun, reaction } from 'mobx'
import axios from 'axios'
class IssuesStore {
@observable issues = []
constructor() {
autorun(() => console.log("Autorun:" + this.buildIssues))
reaction(
() => this.issues,
issues => console.log("Reaction: " + issues.join(", "))
)
}
getIssues(data) {
return data.map((issue) => ({title: issue.name, url: issue.url, labels: issue.labels}))
}
@computed get buildIssues() {
const authToken = 'token ' + process.env.REACT_APP_GH_OAUTH_TOKEN
axios.get(`https://api.github.com/repos/${process.env.REACT_APP_GH_USER}/gh-issues-app/issues`,
{ 'headers': {'Authorization': authToken} })
.then(response => {
console.log(response)
this.issues = this.getIssues(response.data)
return this.issues
})
.catch(function(response) {
console.log(response)
})
}
}
export default IssuesStore
在試圖分開各個組件和存儲API調用的承諾,我拿出了愛可信的呼叫到一個單獨的js文件,作爲函數的集合:
import axios from 'axios'
const authToken = 'token ' + process.env.REACT_APP_GH_OAUTH_TOKEN
export function loadIssues() {
return this.apiPromise(
`https://api.github.com/repos/${process.env.REACT_APP_GH_USER}/gh-issues-app/issues`,
{ 'headers': {'Authorization': authToken} }
)
}
export function apiPromise(endpoint, options) {
return axios.get(endpoint, options)
.then((response) => {
// console.log("response: " + JSON.stringify(response, null, 2))
return response.data.map((issue) => ({title: issue.name, url: issue.url, labels: issue.labels}))
})
.catch(function(response) {
console.log(response)
})
}
現在,我的商店看起來是這樣的:
import { observable, computed, autorun, reaction } from 'mobx'
import * as github from '../api/github'
class IssuesStore {
@observable issues = []
constructor() {
autorun(() => console.log("Autorun:" + this.buildIssues))
reaction(
() => this.issues,
issues => console.log("Reaction: " + issues.join(", "))
)
}
@computed get buildIssues() {
this.issues = github.loadIssues().data
return this.issues
}
}
export default IssuesStore
小得多......但由於它現在看到的issues
作爲初始狀態的網頁現在拋出一個錯誤0在第一次渲染。
Uncaught TypeError: Cannot read property 'map' of undefined
的承諾成功完成以後(因爲它應該),但那時已經太晚了。當然,我可以在我的渲染組件中設置幾個null
檢查,以便在空的或尚未定義的變量上不運行.map
或其他此類函數。
但是爲什麼代碼在重構之前沒有初始渲染錯誤,而不是在之後工作?我認爲重構實際上保持了相同的邏輯流程,但我必須錯過什麼?
謝謝!工作。我對承諾的理解不足以理解爲什麼我需要另一個'.then()'在返回的承諾來獲取我的數據。我認爲承諾中定義的'.then()'足以在響應中獲取我需要的內容。 – changingrainbows