我在 componentWillMount() 中調用了一個異步函數,在返回結果中調用 this.setState() 來保存數據,在 render() 中使用 this.state.article 時,顯示爲 undefined。代碼以下:異步
componentWillMount() {
console.log('componentWillMount called')
let _ = this
// 獲取當前文章 ID;
let postID = utils.getID(ARTICLE)
/**
* @description 獲取、渲染文章內容
* @param {Number} postID - 當前文章 ID
*/
postIO.getDetail(postID).then(res => {
if (res.status === 200) {
console.log('asynchronous called')
let data = res.data
_.setState({
article: {...data},
})
}
})
}
render() {
console.log('render called')
return (
<div></div>
)
}
能夠看到控制檯打印信息:
componentWillMount called
render called
asynchronous called
render called
這裏能夠得出:調用完 componentWillMount() 後,執行 render(),這時 componentWillMount 中的回調函數也執行完畢,更新數據後再次調用 render。
這個問題緣由:首先,異步函數自己就是不會等前一個任務結束後再執行後一個函數,而是在執行其回調函數的同時就開始執行後一個函數了。所以,在調用完 componentWillMount 函數後,執行 postIO.getDetail(postID).then(res => {}),同時執行 render()。
可能致使的問題:在 componentWillMount 中的回調函數中調用 this.setState({article: {...data}}),第一次調用 render 時,是獲取不到 this.state.article 的值的,這樣就會引發報錯。
解決方法:
增長一個加載狀態,默認爲 false,調用 componentWillMount() 時,設置爲 true,當這個加載狀態是 true 時,暫不渲染,當回調函數執行完畢後,設置爲 false,此時再調用 render();
完整代碼以下:
constructor(props) {
super(props)
this.state = {
article: {},
isLoading: false,
}
}
componentWillMount() {
let _ = this
// 獲取當前文章 ID;
let postID = utils.getID(ARTICLE)
_.setState({isLoading: true})
/**
* @description 獲取、渲染文章內容
* @param {Number} postID - 當前文章 ID
*/
postIO.getDetail(postID).then(res => {
if (res.status === 200) {
console.log('asynchronous called')
let data = res.data
_.setState({
article: {...data},
isLoading: false
})
}
})
}
render() {
let {isLoading} = this.state
if (isLoading) {
return <p>isLoading...</p>
}
return (
<div></div>
)
}