重新学习 react 中编程式的路由

以往知识点都很零散,今天来系统的总结一下react中编程式的路由。目前来看主要有两种编程式的路由。

  1. react-router-redux

    说句实在的,体验了一番还是react-router-redux香,简洁明了。以后还是尽量用这个。

    import React from "react";
    import ReactDOM from "react-dom";
    
    import { createStore, combineReducers, applyMiddleware } from "redux";
    import { Provider } from "react-redux";
    
    import createHistory from "history/createBrowserHistory";
    import { Route } from "react-router";
    
    import {
      ConnectedRouter,
      routerReducer,
      routerMiddleware,
      push,
    } from "react-router-redux";
    
    import reducers from "./reducers"; //   导入reducer
    
    // 使用createHistory()创建history对象
    const history = createHistory();
    
    // 创建用语定义和派发导航action的中间件
    const historyMiddleware = routerMiddleware(history);
    
    // 把之前的reducers与react-router-redux提供的routerReducer combine起来,形成一个新的顶级的reducer
    const store = createStore(
      combineReducers({
        ...reducers,
        router: routerReducer,
      }),
      applyMiddleware(historyMiddleware)
    );
    
    // ok,编程导航路由
    store.dispatch(push('/foo'))
    // store.dispatch(push('/bar'))
    // store.dispatch(push('/anywhere-you-want-to-go'))
    
    ReactDOM.render(
        // 使用react-redux提供的provider来提供redux的store
      <Provider store={store}>
          {/* ConnectedRouter 会自动使用store对象 */}
        <ConnectedRouter history={history}>
          <div>
            <Route exact path="/" component={Home} />
            <Route path="/about" component={About} />
            <Route path="/topics" component={Topics} />
          </div>
        </ConnectedRouter>
      </Provider>
    );
    
    
  2. connected-react-router

    // 1. reducer.js文件
    
    import { combineReducers } from "redux";
    import { connectRouter } from "connected-react-router";
    
    export default (history) =>
      combineReducers({
        router: connectRouter(history),
        // ... // 其他的reducer
      });
    
    // 2. configureStore.js文件
    
    //...
    import { createBrowserHistory } from "history";
    import { applyMiddleware, compose, createStore } from "redux";
    import { routerMiddleware } from "connected-react-router";
    //从上面的reducer.js里面导入进来
    import createRootReducerCustomCustomCustom from "./reducers";
    // ...
    
    export const history = createBrowserHistory();
    
    export default function configureStore(preloadedState) {
      const store = createStore(
        createRootReducerCustomCustomCustom(history), // root reducer with router state,
        preloadedState,
        compose(
          applyMiddleware(
            routerMiddleware(history) // for dispatching history actions
            // ... other middlewares ...
          )
        )
      );
      return store;
    }
    
    // 3. index.js 文件
    
    // ...
    import { Provider } from "react-redux";
    import { Route, Switch } from "react-router"; // react-router v4/v5
    import { ConnectedRouter } from "connected-react-router";
    import configureStore, { history } from "./configureStore";
    // ...
    
    const store = configureStore(/* provide initial state if any */);
    ReactDOM.render(
      <Provider store={store}>
        <ConnectedRouter history={history}>
          {" "}
          {/* place ConnectedRouter under Provider */}
          <>
            {" "}
            {/* your usual react-router v4/v5 routing */}
            <Switch>
              <Route exact path="/" render={() => <div>Match</div>} />
              <Route render={() => <div>Miss</div>} />
            </Switch>
          </>
        </ConnectedRouter>
      </Provider>,
      document.getElementById("react-root")
    );