connected-react-router
Galloping_Leo 2021-04-11 React
# connected-react-router
- connected-react-router 这个库帮我们实现了在 redux 中操作路由方法,并将路由变化的信息同步在 redux 的 store 中。
- dispatch 派发 可以带有路由跳转的类型的 action ,派发后由routerMiddleware中间件拦截进行跳转。
- 路径改变的时候 ,可以把当前的路径信息(location)存放到仓库中,router属性里
# 使用步骤
创建 hitory
共享同一个 history
import { createBrowserHistory, createHashHistory } from "history";
// 停工两个工厂方法 创建 history
let history = createHashHistory();
export default history;
1
2
3
4
5
2
3
4
5
Reducers
创建时传入 hitory
import { combineReducers } from "redux";
import { connectRouter } from "../../connected-react-router";
import history from "../history";
import counter from "./counter";
let reducres = combineReducers({
router: connectRouter(history),
//...rest of your reducers
counter,
});
export default reducres;
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
使用中间件 routerMiddleware
import reducers from "./reducers";
import { routerMiddleware } from "../connected-react-router";
import history from "./history";
let store = createStore(reducers, applyMiddleware(routerMiddleware(history)));
export store
1
2
3
4
5
6
2
3
4
5
6
使用 ConnectedRouter
import { ConnectedRouter as Router } from "connected-react-router";
1
<Router history={history}>
{/*根组件*/}
</Router>
1
2
3
2
3
# 实现
import React, { Component } from "react";
import { Router } from "react-router";
import { ReactReduxContext } from "react-redux";
import { LOCATION_CHANGE } from "./constants";
export default class ConnectedRouter extends Component {
static contextType = ReactReduxContext;
componentDidMount() {
// 每当路径发生变化之后 都会执行此监听函数
// 并传入两个参数 location(新路径) action(新动作)
this.unlisten = this.props.history.listen((location, action) => {
console.log("listen")
this.context.store.dispatch({
type: LOCATION_CHANGE,
payload: {
action,
location,
},
});
});
}
componentWillUnmount() {
this.unlisten();
}
render() {
const { history, children } = this.props;
return <Router history={history}>{children}</Router>;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import { LOCATION_CHANGE } from "./constants";
export default (history) => {
// 初始状态
let initState = { action: history.action, location: history.location };
return (state = initState, action) => {
switch (action.type) {
case LOCATION_CHANGE:
return { ...action.payload };
default:
return state;
}
};
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
// 仓库中路由中间件派发动作时使用此
export const CALL_HISTRY_METHOD = "@@router/CALL_HISTRY_METHOD";
// 路径改变时 派发一个动作 跟新 router 属性值
export const LOCATION_CHANGE = "@@router/LOCATION_CHANGE";
1
2
3
4
2
3
4
import { CALL_HISTRY_METHOD } from "./constants";
export default (path) => ({
type: CALL_HISTRY_METHOD,
payload: {
method: "push",
path,
},
});
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
import { CALL_HISTRY_METHOD } from "./constants";
export default (history) => ({ getState, dispatch }) => (next) => (action) => {
if (action.type === CALL_HISTRY_METHOD) {
const { method, path } = action.payload;
history[method](path);
} else {
next(action);
}
};
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9