- 深入理解React Router:從原理到實踐
- 李楊韜
- 482字
- 2021-04-16 16:10:43
2.3.3 history監聽
hashHistory的監聽函數listen接口與browserHistory的接口完全一致:

當location記錄發生變化時,會觸發listen監聽的回調函數。回調函數參數列表中第一個參數location為變化后的地址信息;第二個參數action為跳轉類型,分別為“POP”“PUSH”“REPLACE”。
history的設計風格都是在調用訂閱函數之后返回一個取消訂閱的函數,可調用取消訂閱函數取消history的監聽:

類似于addEventListener可對單個事件添加多個回調函數,history.listen同樣可多次調用,添加多個監聽函數:


對于多次調用監聽函數,也會返回響應的注銷方法,可分別調用注銷方法取消history的監聽。
對于history.listen,類似于瀏覽器的事件訂閱,當監聽到location變化時,會通知監聽函數。在history.listen的源碼實現上,調用history.listen將事件回調函數保存到一個監聽列表中。監聽列表維護了一個回調函數數組,當需要取消響應事件時,則將需要取消的回調函數從這個回調函數數組中移除。當需要通知事件時,對回調函數數組中的每一個函數依次進行調用。其源碼如下:


在上例源碼中,listen將通過checkDOMListeners(1)監聽原生的瀏覽器事件,如popstate事件,參數中的數字表示listen的調用計數。調用一次listen,內存中變量會加1;當移除事件時,內存中變量會減1。只有當值為0時,調用checkDOMListeners(1)才會注冊一次相關原生事件,這樣避免了調用listen多次注冊瀏覽器事件。