connected-react-router

connected-react-router

npm connected-react-router -S

  • 可以通过向仓库派发动作的方式实现路由跳转。
  • 每次路径发生变化时可以把最新的路径放到仓库里面,以便随时在仓库中获取。

使用

connected-react-router

Step 1

创建一个唯一的history对象。

//history.tsx
import {createHashHistory} from 'history';
export default createHashHistory();

step 2

添加routerMiddleware中间件。

import {createStore,applyMiddleware} from 'redux';
import { routerMiddleware } from 'connected-react-router'
import rootReducer from './reducers';
import history from '../history';
let store =  applyMiddleware(routerMiddleware(history))(createStore)(rootReducer);
export default store;

Step 3

在reducers里添加connectRouter;

// store/reducers/index.tsx
import { combineReducers } from 'redux';
import { connectRouter } from 'connected-react-router';
import history from '../../history';
let reducers = {
    //...
    router: connectRouter(history)
}
export default combineReducers(reducers);

Step 4

Route替换为ConnectedRouter

//index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { HashRouter as Router, Route } from 'react-router-dom';
import { ConnectedRouter } from 'connected-react-router'
import Home from './components/Home';
import store from './store';
import history from './history';
ReactDOM.render(
    <Provider store={store}>
        <ConnectedRouter history={history}>
            <Route path='/' exact component={Home} />
            {/*...*/}
        </ConnectedRouter>
    </Provider>
    , document.getElementById('root'));

Step 5

添加action,使用push返回action对象。

//store/actions/counter.tsx
import {push} from 'connected-react-router';
export default {
    goto(path:string,state?:any){
        return push(path,state);
    }
}

原理

index.tsx

import connectRouter from './connectRouter';
import push from './push';
import ConnectedRouter from './ConnectedRouter';
import routerMiddleware from './routerMiddleware';

export {
    ConnectedRouter,
    connectRouter,
    routerMiddleware,
    push
}
export * from './types';

types.tsx

export const REDUX_PUSH: '@@REDUX_PUSH' = '@@REDUX_PUSH';
export const REDUX_CHANGE: '@@REDUX_CHANGE' = '@@REDUX_CHANGE';

push.tsx

import { REDUX_PUSH } from './';
export default function (...args: any[]) {
    return {
        type: REDUX_PUSH,
        payload: {
            method: 'push',
            args: args
        }
    }
}

routerMiddleware.tsx

import { REDUX_PUSH } from './';
import { MiddlewareAPI, AnyAction } from 'redux';
export default function (history: any) {
    return (api: MiddlewareAPI) => (next: any) => (action: AnyAction) => {
        if (action.type === REDUX_PUSH) {
            let { method, args } = action.payload;
            history[method](...args);
        } else {
            next(action);
        }
    }
}

ConnectedRouter.tsx

import React from 'react';
import { Router } from 'react-router';
import { History } from 'history';
import { ReactReduxContext } from 'react-redux';
import { REDUX_CHANGE } from '.';
export interface Props {
    history: History
}

export interface State {

}

export default class extends React.Component<Props, State> {
    static contextType = ReactReduxContext
    unListener: any
    componentDidMount() {
        this.unListener = this.props.history.listen((location, action) => {
            this.context.store.dispatch({
                type: REDUX_CHANGE,
                payload: {
                    location,
                    action
                }
            });
        })
    }
    componentWillUnmount() {
        this.unListener();
    }
    render() {
        return <Router history={this.props.history}>
            {this.props.children}
        </Router>;
    }
}

connectRouter.tsx

import { REDUX_CHANGE } from './';
import { History } from 'history';
import { AnyAction } from 'redux';
export default function (history: History) {
    return function (state = {}, action: AnyAction) {
        if (action.type === REDUX_CHANGE) {
            return action.payload
        } else {
            return state;
        }
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 路由相关的库还有一个connected-react-router,这个库做到了以下几点 将 router 的数据与...
    吴晗君阅读 4,972评论 0 2
  • 今天我们介绍的connected-react-router是redux用来绑定路由的。 如果还没有看过我之前关于r...
    龚达耶阅读 11,222评论 2 4
  • React Router 4.0 (以下简称 RR4) 已经正式发布,它遵循React的设计理念,即万物皆组件。所...
    梁相辉阅读 97,779评论 24 195
  • React Router教程 React项目的可用的路由库是React-Router,当然这也是官方支持的。它也分...
    IT老马阅读 58,999评论 0 49
  • 闹钟响了三次,我才肯起床。 早上好,坚持早起的我。 听说本周末又有一波冷空气,冷……
    诗水年华阅读 188评论 2 0