先上結論,不是取不到,是寫法有問題。react
全文分4部分,1是問題描述,2是一開始的解決想法(錯誤作法),3是問題產生緣由的思考,4是正常解決方法。只想看結論直接跳4框架
1.問題描述異步
接觸react dva一個月,和同事都不算熟悉框架。在修改、使用同事的ui組件時,想用全局model保存的state來給組件state一個初始值,但組件中取不到登陸後異步獲取的用戶信息。ide
在組件constructor中取不到(僅有model state初始化的值,無異步獲取的信息),但在組件使用時render中能夠console出須要的值ui
if(!this.state.needData) { this.setState({ needData: this.props.modelName.needData }) }
3.思考問題緣由this
下班後思考問題緣由。首先,根據props初始化組件state是符合操做邏輯的,不可能不支持;其次,組件中有時能取到,有時取不到。因此必定是我使用有問題,並且較大能夠是在錯誤的時間使用了組件。spa
那就須要定位問題所在,這時候console是個簡單原始,但確實有效的幫手。code
把頁面入口組件(0)問題組件constructor(1)問題組件render(2)model setup(3)異步數據獲取到(4)分別加上consoleblog
仔細看這個結果,也就不可貴出結論了。生命週期
組件constructor初始化組件在異步數據加載以前就已經完成,且數據加載之後,全局state修改觸發的從新渲染並不會影響到constructor,其在組件生命週期裏僅會執行一次。
而查看該組件調用處發現,該組件是否顯示(彈出組件,非一直顯示)是把控制的flag傳入了組件裏,在組件內部控制是否顯示。這種方式其實僅能控制組件內的元素是否顯示,沒法控制組件自己是否存在。正是這個緣由,致使了組件在頁面加載的以後便已經初始化完畢,以後僅控制顯示與否。這其實不利於頁面加載速度,也不符合按需加載的思想,還會致使異步數據初始化組件失敗。因此我以爲不是個好的寫法。
那麼也就有了第二種,我認爲正確的解決方案
4.解決方法二
由3能夠知道,組件在異步數據到來前已經完成初始化,是致使constructor中沒法取到所需數據的緣由。因此最直接的方法,就是修改組件建立的時間
//把原來的組件內部控制顯示 /* <ComponentName show={modelName.show}/> */ //更改成狀態直接控制組件是否存在 { modelName.show && <ComponentName/> } //或者 { modelName.show ? <ComponentName/> : null } //或者更嚴謹一點 //因爲項目中加入了用戶數據獲取失敗,需從新登陸,因此也就沒有加上後面這個 { modelName.show && modelName.needData && <ComponentName/> }
修改後
目標組件不會在頁面加載時就初始化
而是在用戶點擊控制按鈕,須要使用組件時,才初始化
到此問題算是真正解決。
由此問題,也讓我對model加載、頁面初始化、有狀態組件初始化、組件生命週期,有了更深的理解,算是有些收穫。