關於setRouteLeaveHook無法使用時的替代方案registerTransitionHook

swinblacksea發表於2018-11-30
背景:首先說明下,這個問題很奇怪,花了整整一天在google上搜了一圈沒有結果,深夜加班到10:30還是沒有效果。但是進度在一點點往前走,並且確認解題大方向沒有問題所以也一直沒有放棄。下面介紹下具體問題:
鉤子:我們知道reactRouter中有一個路由鉤子,這個鉤子可以針對某個元件(父或子)在遇到具體事件時觸發回撥,相當於攔截事件觸發做內建於鉤子hook中的方法。
需求:切換路由時觸發鉤子進行使用者提示是否離開目前路由
方案(google):
componentDidMount(){
this.props.router.setRouteLeaveHook(
            this.props.route,
            this.routerWillLeave
        )

}

routerWillLeave(nextLoac) {
        return "you sure you want to leave?" ;
}


另外需要注意的是:router的注入,withRouter對router的組裝之類的,這個google上都有,這裡只說我遇到的問題,目前為止在google上還沒有被發現

一通操作猛如虎,一看結果驚呆了,始終沒有效果,打了console一直沒法進入鉤子函式routerWillLeave,經過不斷嘗試之後發現一個問題:在不重新整理的情況下改變本js任何程式碼哪怕多一個或少一個空格然後編譯,效果就出來了。一直不太明白到底什麼原因,如果有看到的大神麻煩解釋下,謝謝。
後來在一次意外中發現router裡面還有個registerTransitionHook,之所以注意到這個是因為在debug上面程式碼時發現出效果的情況會進入到一個叫transitionHook的方法,所以我想如果不用setRouteLeaveHook直接使用registerTransitionHook是不是會達到同樣的效果,因為我用的是antd-react-dva一套,而router已經被dva封裝了一層,擔心之所以setRouteLeaveHook沒有是因為這個原因,所以就在google registerTransitionHook。一搜一個準,https://github.com/ReactTraining/history/issues/14這個大神說他就是用這個來實現我想要的效果的,但是人家是用history,dva裡面history從哪來?直接從父元件傳遞下來應該就可以了,但是因為router裡面就有這個方法,何必使用history,果斷把history改為this.props.router測試一把,搞定。
效果是有了,另外把google大神其他的助攻隨便說下吧,避免你們再找來找去了。此處會有一個小bug,你切換任何一個路由都會有彈框,怎麼辦?在componentWillUnmount裡面使用unregisterTransitionHook方法把鉤子撤銷掉,但是需要注意:必須是同一個鉤子,怎麼做?在constructor裡面繫結就好
constructor(props) {
        super(props);
        this.routerWillLeave = this.routerWillLeave.bind(this)
    }

 //離開該頁面時刪除該監聽事件
    componentWillUnmount() {
   this.props.router.unregisterTransitionHook(this.routerWillLeave)
    }

因為太激動了,所以寫下這邊博文以作紀念,哈哈


相關文章