React 中使用React-Router

React-Router帮助我们实现单页应用的路由跳转功能

1. 简单路由

  • src/pags/home.js
const Home = () => {
  return (
    <div>Home</div>
  );
};
  • src/Routes.js
import React from 'react';
import { Router, Route, browserHistory } from 'react-router';

import Home from './pages/Home.js';
import About from './pages/About.js';
import NotFound from './pages/NotFound.js';

const history = browserHistory;
const Routes = () => (
  <Router history={browserHistory}>
    <Route path="home" component={home} />
    <Route path="about" component={About} />
    <Route path="*" component={NotFound} />
  <Router>
);

export default Routes;
  • src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Routes from './Routes.js';

ReactDOM.render(
  <Routes />,
  document.getElementById('root')
);

2. 路由的链接和嵌套

  • src/TopMenu/index.js
import React from 'react';
import {Link} from 'react-router';
const view = () => {
  return (
    <div>
      <ul>
        <li style={liStyle}><Link to="/home">Home</Link></li>
        <li style={liStyle}><Link to="/about">About</Link></li>
      </ul>
    </div>
  );
};

export { view };
  • src/pages/App.js
import React from 'react';
import { view as TopMenu } from '../components/TopMenu';
const App = ({children}) => {
  return (
    <div>
      <TopMenu />
      <div>{children}</div>
    </div>
  );
};
export default App;
  • src/Routes.js
// IndexRoute 设置默认路由
const Routes = () => (
  <Router history={history}>
    <Route path="/" component={App}>
      <IndexRoute component={Home} />
      <Route path="home" component={home} />
      <Route path="about" component={About} />
      <Route path="*" component={NotFound} />
    </Route>
  <Router>
);

3. 集成Redux

ReactDOM.render(
  <Provider store={store} >
    <Routes />
  </Provider>,
  document.getElementById('root')
);

使用react-router-redux同步浏览器url和Redux状态

import {routerReducer, syncHistoryWithStore } from 'react-router-redux';
const reducer = combine({
  routing: routerReducer
});

// 将browserHistory与Store关联
const history = syncHistoryWithStore(browserHistory, store);

4. 动态加载分片

完成动态加载分片要两个方面:

  • 使用require.ensure让webpack产生分片打包文件;
  • 使用React-Router的getComponent异步加载页面分片文件

src/Routes.js

const getHomePage = (location, callback) => {
  require.ensure([], function(require) {
    callback(null, require('./pages/Home.js').default);
  }, 'home');
};

const getAboutPage = (location, callback) => {
  require.ensure([], function(require) {
    callback(null, require('./pages/About.js').default);
  }, 'about');
};

const getNotFoundPage = (location, callback) => {
  require.ensure([], function(require) {
    callback(null, require('./pages/NotFound.js').default);
  }, '404');
};
const Routes = () => (
  <Router history={history} createElement={createElement} >
    <Route path="/" component={App}>
      <Route path="home" getComponent={getHomePage} />
      <Route path="about" getComponent={getAboutPage} />
      <Route path="*" getComponent={getNotFoundPage} />
    </Route>
  </Router>
);

动态更新Store的reducer和状态

import {combineReducers} from 'redux';
const getCounterPage = (nextState, callback) => {
  require.ensure([], function(require){
    const { page, reducer, stateKey, initialState} = require('./pages/counterPage.js');
    const state = store.getState();
    store.reset(combineReducers({
      ...store._reducers,  // 原始的reducer
      counter: reducer
    }), {
      ...state,
      [stateKey]: initialState
    });
    callback(null, page);
  }, 'counter');
};
posted @ 2023-03-06 17:59  箫笛  阅读(85)  评论(0)    收藏  举报