git clone https://github.com/ReactTraining/react-router.git
packages
react-router 使用Demo
// #: npx create-react-app demo-app
// #: cd demo-app
// #: npm install react-router-dom
// 例子 1
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
export default function App() {
return (
<Router>
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/users">Users</Link>
</li>
</ul>
</nav>
{/* A <Switch> looks through its children <Route>s and
renders the first one that matches the current URL. */}
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/users">
<Users />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</div>
</Router>
);
}
function Home() {
return <h2>Home</h2>;
}
function About() {
return <h2>About</h2>;
}
function Users() {
return <h2>Users</h2>;
}
// 例子 2
import {
BrowserRouter as Router,
Switch,
Route,
Link,
useRouteMatch,
useParams
} from "react-router-dom";
export default function App() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/topics">Topics</Link>
</li>
</ul>
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/topics">
<Topics />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</div>
</Router>
);
}
function Home() {
return <h2>Home</h2>;
}
function About() {
return <h2>About</h2>;
}
function Topics() {
let match = useRouteMatch();
return (
<div>
<h2>Topics</h2>
<ul>
<li>
<Link to={`${match.url}/components`}>Components</Link>
</li>
<li>
<Link to={`${match.url}/props-v-state`}>
Props v. State
</Link>
</li>
</ul>
{/* The Topics page has its own <Switch> with more routes
that build on the /topics URL path. You can think of the
2nd <Route> here as an "index" page for all topics, or
the page that is shown when no topic is selected */}
<Switch>
<Route path={`${match.path}/:topicId`}>
<Topic />
</Route>
<Route path={match.path}>
<h3>Please select a topic.</h3>
</Route>
</Switch>
</div>
);
}
function Topic() {
let { topicId } = useParams();
return <h3>Requested topic ID: {topicId}</h3>;
}
react-router-dom 阅读入门
打开packages目录,在继续打开react-router-dom目录
里面有一个 rollup.config.js 此文件是用来build用的
input: "modules/index.js",
output: {
file: `cjs/${pkg.name}.js`,
sourcemap: true,
format: "cjs",
esModule: false
},
打开index.js查看,我们发现目录中是没有cjs目录的,cjs目录由modules/index.js生成
"use strict";
if (process.env.NODE_ENV === "production") {
module.exports = require("./cjs/react-router-dom.min.js");
} else {
module.exports = require("./cjs/react-router-dom.js");
}
modules/index.js
export {
MemoryRouter,
Prompt,
Redirect,
Route,
Router,
StaticRouter,
Switch,
generatePath,
matchPath,
withRouter,
useHistory,
useLocation,
useParams,
useRouteMatch
} from "react-router";
export { default as BrowserRouter } from "./BrowserRouter.js";
export { default as HashRouter } from "./HashRouter.js";
export { default as Link } from "./Link.js";
export { default as NavLink } from "./NavLink.js";
modules/HashRouter.js
import React from "react";
import { Router } from "react-router";
import { createHashHistory as createHistory } from "history";
import PropTypes from "prop-types";
import warning from "tiny-warning";
/**
* The public API for a <Router> that uses window.location.hash.
*/
class HashRouter extends React.Component {
history = createHistory(this.props);
render() {
return <Router history={this.history} children={this.props.children} />;
}
}
if (__DEV__) {
HashRouter.propTypes = {
basename: PropTypes.string,
children: PropTypes.node,
getUserConfirmation: PropTypes.func,
hashType: PropTypes.oneOf(["hashbang", "noslash", "slash"])
};
HashRouter.prototype.componentDidMount = function() {
warning(
!this.props.history,
"<HashRouter> ignores the history prop. To use a custom history, " +
"use `import { Router }` instead of `import { HashRouter as Router }`."
);
};
}
export default HashRouter;
modules/BrowserRouter.js
import React from "react";
import { Router } from "react-router";
import { createBrowserHistory as createHistory } from "history";
import PropTypes from "prop-types";
import warning from "tiny-warning";
/**
* The public API for a <Router> that uses HTML5 history.
*/
class BrowserRouter extends React.Component {
history = createHistory(this.props);
render() {
return <Router history={this.history} children={this.props.children} />;
}
}
if (__DEV__) {
BrowserRouter.propTypes = {
basename: PropTypes.string,
children: PropTypes.node,
forceRefresh: PropTypes.bool,
getUserConfirmation: PropTypes.func,
keyLength: PropTypes.number
};
BrowserRouter.prototype.componentDidMount = function() {
warning(
!this.props.history,
"<BrowserRouter> ignores the history prop. To use a custom history, " +
"use `import { Router }` instead of `import { BrowserRouter as Router }`."
);
};
}
export default BrowserRouter;
HashRouter 与 BrowserRouter的区别
HashRouter 是基于Hash的 也就是浏览器地址栏中的#xxx 锚定位,锚链接
BrowserRouter [ˈbraʊzə(r)] 浏览器,是基于H5 history 这个我们放到后面章节仔细分析