概述
在上篇 dva router4.0 使用實踐總結 中主要介紹了 dva 中使用 react-router@4.0 標簽寫法控制路由。如下:
<Switch>
<Route path="/" exact render={() => (<Redirect to="/dashboard" />)} />
{
routes.map(({ path, ...dynamics }, key) => (
<Route
exact
key={key}
path={path}
component={dynamic({ app, ...dynamics })}
/>
))
}
<Route component={error} />
</Switch>
但是實際開發中,我們可能會需要在代碼中進行路由的跳轉。本文主要介紹在 dva 中使用代碼進行路由跳轉以及參數傳遞。
理清關系
dva 升級到 2.0 版本以后,也將內部使用的 dva/router 從 react-router@3.0 升級到了 react-router@4.0。react-router@4.0 文檔 API
react-router@4.0 讓路由變得更簡單,最大特點就是可以路由嵌套,可是如果照搬使用 react-router@4.0 的寫法,你會發現在 dva 中是行不通的,查看 dva/router 的源碼可以看到:
// dva/router.js
module.exports = require('react-router-dom');
module.exports.routerRedux = require('react-router-redux');
其中第一行導出的react-router-dom
就是 react-router@4.0 文件,第二行導出的react-router-redux
是 react-router 配合 redux 使用的中間庫。因為 dva 中使用到了 redux,所以我們在配置的時候還需要注意到這一點。
由于 dva 將react-router-dom
和react-router-redux
都封裝到了 dva/router 中,在使用 react-router@4.0 和 redux 里面的東西時只需引入 dva/router 這個包即可。
路由跳轉
引入 dva/router
,使用 routerReux 對象的 push 方法控制,值為要跳轉的路由地址,與根目錄下 router.js 中配置的路由地址是相同的。routerReux 就是上面 dva/router
第二個導出的 react-router-redux
包對象。
此處示例為跳轉到 /user
路由。
// models > app.js
import { routerRedux } from 'dva/router';
export default {
// ...
effects: {
// 路由跳轉
* redirect ({ payload }, { put }) {
yield put(routerRedux.push('/user'));
},
}
// ...
}
攜帶參數
有時路由的跳轉還需要攜帶參數。
傳參:
routerRedux.push 方法的第二個參數填寫參數對象。此處示例表示跳轉到 /user
路由,并攜帶參數 {name: 'dkvirus', age: 20}
。
// models > app.js
import { routerRedux } from 'dva/router';
export default {
// ...
effects: {
// 路由跳轉
* redirect ({ payload }, { put }) {
yield put(routerRedux.push('/user', {name: 'dkvirus', age: 20}));
},
}
// ...
}
接收參數:
// models > user.js
export default {
subscriptions: {
/**
* 監聽瀏覽器地址,當跳轉到 /user 時進入該方法
* @param dispatch 觸發器,用于觸發 effects 中的 query 方法
* @param history 瀏覽器歷史記錄,主要用到它的 location 屬性以獲取地址欄地址
*/
setup ({ dispatch, history }) {
history.listen((location) => {
console.log('location is: %o', location);
console.log('重定向接收參數:%o', location.state)
// 調用 effects 屬性中的 query 方法,并將 location.state 作為參數傳遞
dispatch({
type: 'query',
payload: location.state,
})
});
},
},
effects: {
*query ({ payload }, { call, put }) {
console.log('payload is: %o', payload);
}
}
// ...
}
在 user.js 中 subscriptions 屬性會監聽路由。當 app.js 中通過代碼跳轉到 /user
路由,models>user.js>subscriptions 屬性中的 setup 方法會被觸發,location 記錄著相關信息。打印如下。
location is: Object
hash: ""
key: "kss7as"
pathname: "/user"
search: ""
state: {name: "bob", age: 21}
重定向接收參數:Object
age:21
name:"bob"
可以看到 location.state
就是傳遞過來的參數。在 subscriptions 中可以使用 dispatch 觸發 effects 中的方法同時傳遞參數。
需要注意的事,在 dva@1.* 版本中,要獲取對象還要用 location.query
對象,而到了 dva@2.* 就變成了 location.state
對象。