redux和react虛擬dom的關係?
provider將store/state和app綁定,每次dispatch都會引起render不過因為虛擬dom的存在,通過diff演算法比較的差異才會修改真實的dom,是我這麼理解的嗎?
——修改一下問題十分感謝@魯小夫 。另外根據回答,想問的是mapstatetoprops和shouldcomponentupdate的關係是不是只要connect的組件都是對rootstate的監聽,不過shold……里只去關心mapstate……的欄位
謝邀。
redux 跟 virtual dom 沒有關係。
「provider將store/state和app綁定」
錯。provider 將 store 綁定在 context 上。
connect() 和mapStateToProps()/mapDispatchToProps() 則是組件調用 context 上的 store 的標準方法。「每次dispatch都會引起render」錯。每次 dispatch 都會調用 reducer ,然後 shouldComponentUpdate() ,但不一定能走到 render() 。一點關係都沒有。
似乎題主用了react-redux這個庫,這個庫只是react和redux的橋樑,connect函數產生了一個新的HOC函數,這個新的HoC函數把一個React組件包了一個新的React容器組件,這個新的容器組件實現了shouldComponentUpdate,避免了大量重複渲染。
先說結論,redux和react dom沒有直接關係。
畫了幾張圖幫助理解一下。我們先不看Redux,一個標準的React組件會由以下幾種情況觸發render。
一種是通過setState方法設置了state內容,另一種是外部傳入了props。當未做任何優化的情況下,只要調用setState 或者 傳入props都會使組件調用render(無論props或者state和原先的內容是否相同)。如果該組件render中包含子組件,那麼子組件也會一同觸發render。(如果是根組件render,那麼整個虛擬dom樹都會被render一次)
當虛擬dom樹render完成後,react會將其和之前的虛擬dom樹進行對比。如果發現有變化,那麼就會改變對應的實際dom節點。如果沒有,則不做改動。(由於實際的dom操作比較耗時,所以跳過的dom操作也是react渲染性能優勢的原因)connect = (mapStateToProps, ...) =&> {
// ...
return (Component) =&> {
// ...
return class extends React.Component {
render() {
const props = {};
// 通過mapStateToProps填充props
// ...
return & 實際上還是通過react來對虛擬dom進行控制。(此外connect也重寫了shouldComponentUpdate來優化渲染)
}
}
}
}
redux和react的虛擬dom沒有關係,readux只是一種設計思想,是前端再寫頁面應用時所使用的一種前端架構,這個架構源於flux而來,避免了flux的複雜性,如果你對flux了解,對這個也會很快學會,&
組件使得組件層級匯總的connect()方法能夠獲得redux store,正常情況下,你的根組件應該嵌套在&
react中的虛擬dom是為了讓react更加高效而採用的一種方法,因為我們應用越來越複雜,我們的js代碼要管理頁面dom的更新會很複雜,對於dom的更新我們可以先緩存起來,等到在我們完全修改完成之後再修改到實際的dom中,這就和我們一般dom操作是一樣的,先離線操作,等到完成之後,把所有的修改在實際應用到真實的dom中。
而虛擬dom的演算法還是比較複雜的,一般要經歷以下幾個步驟,js現在內存中構建出這個虛擬dom樹,然後通過虛擬dom構建真正的dom,然後生成新的虛擬dom,比較兩課虛擬dom樹的不同,在真正的dom元素上應用變更。組件重新渲染只有兩用途徑,一是自身調用setState,二是父組件傳入新的props。但這兩種途徑都不會必然調用render而引起重新渲染,會先經過shouldComponentUpdate進行判斷。而一旦一個組件的shouldComponentUpdate返回true,調用了render,就會對該組件的所有子組件傳入新的props,因此所有子組件都會可能重新渲染(依然決定於每一個子組件shouldComponentUpdate的返回值)。
redux用connect綁定組件後,調用dispatch會根據action修改reducer里相應的state分支(這個state不是組件的state,是redux的state),此時redux會對state的變化進行差異比較(這裡有點類似組件自身的shouldComponentUpdate),如果有變化則會對綁定了對應的redux state分支的組件傳入新的props(如果一個組件綁定的所有redux state分支都沒有變化,則該組件不受任何影響),之後組件內部的變化和普通方式傳入新props的變化是一模一樣的。推薦閱讀:
※redux中所有state都要放在store里嗎?
※寫在2017的前端數據層不完全指北
※感覺redux寫起來很麻煩,目前有那些其他的狀態管理方案?
※MobX vs Redux: Comparing the Opposing Paradigms - React Conf 2017 紀要