connected-react-router

connected-react-router

npm connected-react-router -S

  • 可以通過向倉庫派發(fā)動作的方式實(shí)現(xiàn)路由跳轉(zhuǎn)。
  • 每次路徑發(fā)生變化時可以把最新的路徑放到倉庫里面,以便隨時在倉庫中獲取。

使用

connected-react-router

Step 1

創(chuàng)建一個唯一的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;
        }
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 路由相關(guān)的庫還有一個connected-react-router,這個庫做到了以下幾點(diǎn) 將 router 的數(shù)據(jù)與...
    吳晗君閱讀 5,080評論 0 2
  • 今天我們介紹的connected-react-router是redux用來綁定路由的。 如果還沒有看過我之前關(guān)于r...
    龔達(dá)耶閱讀 11,409評論 2 4
  • React Router 4.0 (以下簡稱 RR4) 已經(jīng)正式發(fā)布,它遵循React的設(shè)計理念,即萬物皆組件。所...
    梁相輝閱讀 98,053評論 24 195
  • React Router教程 React項(xiàng)目的可用的路由庫是React-Router,當(dāng)然這也是官方支持的。它也分...
    IT老馬閱讀 59,302評論 0 49
  • 鬧鐘響了三次,我才肯起床。 早上好,堅持早起的我。 聽說本周末又有一波冷空氣,冷……
    詩水年華閱讀 194評論 2 0

友情鏈接更多精彩內(nèi)容