先上結論,不是取不到,是寫法有問題。
全文分4部分,1是問題描述,2是一開始的解決想法(錯誤做法),3是問題產生原因的思考,4是正常解決方法。只想看結論直接跳4
1.問題描述
接觸react dva一個月,和同事都不算熟悉框架。在修改、使用同事的ui組件時,想用全局model保存的state來給組件state一個初始值,但組件中取不到登錄后異步獲取的用戶信息。
在組件constructor中取不到(僅有model state初始化的值,無異步獲取的信息),但在組件使用時render中可以console出需要的值

if(!this.state.needData) { this.setState({ needData: this.props.modelName.needData }) }
3.思考問題原因
下班后思考問題原因。首先,根據props初始化組件state是符合操作邏輯的,不可能不支持;其次,組件中有時能取到,有時取不到。所以一定是我使用有問題,而且較大可以是在錯誤的時間使用了組件。
那就需要定位問題所在,這時候console是個簡單原始,但確實有效的幫手。
把頁面入口組件(0)問題組件constructor(1)問題組件render(2)model setup(3)異步數據獲取到(4)分別加上console
仔細看這個結果,也就不難得出結論了。
組件constructor初始化組件在異步數據加載之前就已經完成,且數據加載以后,全局state修改觸發的重新渲染並不會影響到constructor,其在組件生命周期里僅會執行一次。
而查看該組件調用處發現,該組件是否顯示(彈出組件,非一直顯示)是把控制的flag傳入了組件里,在組件內部控制是否顯示。這種方式其實僅能控制組件內的元素是否顯示,無法控制組件本身是否存在。正是這個原因,導致了組件在頁面加載的之后便已經初始化完畢,之后僅控制顯示與否。這其實不利於頁面加載速度,也不符合按需加載的思想,還會導致異步數據初始化組件失敗。所以我覺得不是個好的寫法。
那么也就有了第二種,我認為正確的解決方案
4.解決方法二
由3可以知道,組件在異步數據到來前已經完成初始化,是導致constructor中無法取到所需數據的原因。所以最直接的方法,就是修改組件創建的時間
//把原來的組件內部控制顯示 /* <ComponentName show={modelName.show}/> */ //更改為狀態直接控制組件是否存在 { modelName.show && <ComponentName/> } //或者 { modelName.show ? <ComponentName/> : null } //或者更嚴謹一點 //由於項目中加入了用戶數據獲取失敗,需重新登錄,所以也就沒有加上后面這個 { modelName.show && modelName.needData && <ComponentName/> }
修改后
目標組件不會在頁面加載時就初始化
而是在用戶點擊控制按鈕,需要使用組件時,才初始化
到此問題算是真正解決。
由此問題,也讓我對model加載、頁面初始化、有狀態組件初始化、組件生命周期,有了更深的理解,算是有些收獲。