前言
- 有個小夥伴發問:爲什麼一個組件要用withRouter包裹?不是使用了connected-react-router把路由信息存到store了嗎?
- 我仔細一想,覺得很有道理,其實確實可以不通過withRouter包裹獲取history方法。
前置知識
正常寫法
- connected-react-router提供一個
import { ConnectedRouter } from "connected-react-router";
組件,用來替換以前寫法中做Router然後傳history的寫法。
- 正常的組件只要通過Route包裹或者withRouter即可拿到history提供的路由跳轉等方法。
- 那麼,現在問題就是,能不能不通過withRouter或者Route包裹也可以獲取改變路由的方法?
不通過withRouter或者Route包裹獲取改變路由的方法
- 我一開始也沒注意這個問題,畢竟正常寫也能獲取到,直到這個小夥伴發問,我才覺得按理說不通過withRouter和Route也是可以獲得改變路由的方法的。畢竟connected-react-router把路由信息存放到了store中,而其改變store中路由信息,必然要dispatchAction,那麼如果store中路由信息改變,真實路由沒改變,那肯定會有問題,所以dispatch必然藉助了history的方法制作而成,而我們只要拿到dispatch方法即可改變路由。
- 以回退爲例,事實上connectRouter可以導出goBack使用:
import { goBack } from "connected-react-router";
- 這個goBack其實相當於我們寫的dispatchAction。
- 可以通過對組件進行connect連接store:
export default connect((state) => state, { goBack })(Components);
- 將goBack作爲對象映射到組件屬性上,通過props.goBack派發action改變store:
<button onClick={() => props.goBack()}>+++</button>
- 這樣頁面也可以生效。
- 當然我們可以不連接store,畢竟所有conncet組件會進行更新操作,這樣非常影響性能,還記得store可以進行dispatch操作吧,導出store,利用store進行派發即可:
<button onClick={() => Store.dispatch(goBack())}>+++</button>
- 這種直接派發思路其實挺好,對於如果派發一個action並不會使得此組件更新狀態就很有幫助,因爲組件沒有conncect store,不會使得store數據變化造成props變化而刷新組件。(我已測試確實不會刷新)。