由于文字太长,所以截取了部分文字,感兴趣可以关注我的公众号《人生代码》
原文在此
(重磅来袭)react-router-dom 简明教程
react-router-dom 简明教程
我们需要创建 react-pro 项目
create-react-app react-pro
cd react-pro
yarn add react-router-dom
我们看到的目录如下:
在 src 下新建一个 HelloRouter.js,代码如下:
import React, { PureComponent } from 'react';
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
// 将路由拆分成数组的形式,有点像 vue 路由配置
const routes = [
{
to: '/',
content: 'Home'
},
{
to: '/about',
content: 'About'
},
{
to: '/users',
content: 'Users'
}
]
// 创建组件的一种形式,变量的形式
const lis = routes.map((item, index) => {
return (
<li key={index}>
<Link to={item.to}>
{item.content}
</Link>
</li>
)
})
// 类组件的形式
class Home extends PureComponent {
render() {
return <h2>Home</h2>;
}
}
class About extends PureComponent {
render() {
return <h2>About</h2>;
}
}
class Users extends PureComponent {
render() {
return <h2>Users</h2>;
}
}
// 这里的 Switch Route 有点类似 js 中的 switch case 表示精准匹配
export default class HelloRouter extends PureComponent {
render() {
return (
<Router>
<div>
<nav>
<ul>
{lis}
</ul>
</nav>
{/* A <Switch> looks through its children <Route>s and
renders the first one that matches the current URL. */}
<Switch>
<Route path="/about" component={About} />
<Route path="/users" component={Users} />
<Route path="/" component={Home} />
</Switch>
</div>
</Router>
);
}
}
效果如下:
嵌套路由
接下来我们就来写写 react 的嵌套路由;
首先我们在 src 下新建一个 QianTaoRouter.js,具体代码如下:
import React, { PureComponent } from 'react';
import {
BrowserRouter as Router,
Switch,
Route,
Link,
useParams,
useRouteMatch
} from "react-router-dom";
const routes = [
{
to: '/',
content: 'Home'
},
{
to: '/about',
content: 'About'
},
{
to: '/users',
content: 'Users'
},
{
to: '/topics',
content: 'Topics'
}
]
const lis = routes.map((item, index) => {
return (
<li key={index}>
<Link to={item.to}>
{item.content}
</Link>
</li>
)
})
class Home extends PureComponent {
render() {
return <h2>Home</h2>;
}
}
class About extends PureComponent {
render() {
return <h2>About</h2>;
}
}
class Users extends PureComponent {
render() {
return <h2>Users</h2>;
}
}
function Topic() {
let { topicId } = useParams();
return <h3>Requested topic ID: {topicId}</h3>;
}
function Topics() {
let match = useRouteMatch();
console.log("matach", match)
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>
);
}
export default class HelloRouter extends PureComponent {
render() {
return (
<Router>
<div>
<nav>
<ul>
{lis}
</ul>
</nav>
{/* A <Switch> looks through its children <Route>s and
renders the first one that matches the current URL. */}
<Switch>
<Route path="/about" component={About} />
<Route path="/users" component={Users} />
<Route path="/topics" component={Topics} />
<Route path="/" component={Home} />
</Switch>
</div>
</Router>
);
}
}
其中引人注意的是
- useRouteMatch 用于解析路由对象
- useParams 用于解析路由参数
主要组件
路由组件: BrowserRouter和HashRouter
BrowserRouter使用浏览器的History API来管理url及与浏览器进行交互, 需要服务器增加配置以让所有的url请求返回同一个页面
HashRouter将页面当前位置存储在url的hash部分(http://example.com/#/your/page.),不需要服务器增加特殊配置
路由匹配组件Route和Switch
Switch组件搜索其下路由Route组件,渲染第一个匹配到的路由而忽略其他 Route为视图渲染出口
<Switch>
<Route path={`${match.path}/:topicId`}>
<Topic />
</Route>
<Route path={match.path}>
<h3>Please select a topic.</h3>
</Route>
</Switch>
导航组件Link,NavLink和Redirect
Link组件用来在应用中创建链接。Link会被渲染成a标签
<ul>
<li>
<Link to={`${match.url}/components`}>Components</Link>
</li>
<li>
<Link to={`${match.url}/props-v-state`}>
Props v. State
</Link>
</li>
</ul>
NavLink是一种特殊类型的Link,支持自动添加active class
<NavLink to="/react" activeClassName="hurray">
React
</NavLink>
// When the URL is /react, this renders:
// <a href="/react" className="hurray">React</a>
// When it's something else:
// <a href="/react">React</a>
任何时候你想强制导航,你可以渲染一个Redirect组件。当渲染时,它将使用其来支持导航
<Redirect to="/login" />
代码分割
即code-splitting, 网页的增量下载, 未使用到的包不会加载 我们使用webpack, @babel/plugin-syntax-dynamic-import, 和 loadable-components来实现代码分割 首先安装依赖包
yarn add @babel/preset-react @babel/plugin-syntax-dynamic-import loadable-components --dev
配置.babelrc文件(没有的话在项目根目录下新建一个)
{
"presets": ["@babel/preset-react"],
"plugins": ["@babel/plugin-syntax-dynamic-import"]
}
修改App.js
import React from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import loadable from "@loadable/component";
import Loading from "../components/Loading";
import "./App.css";
const Counter = loadable(() => import("../features/counter/Counter"), {
fallback: <Loading />,
});
const Book = loadable(() => import("../features/book/Book"), {
fallback: <Loading />,
});
function App() {
return (
<Router>
<Switch>
<Route exact path="/" component={Counter} />
<Route path="/book" component={Book} />
</Switch>
</Router>
);
}
export default App;
滚动状态恢复
当路由切换时候页面自动滚动到顶部或者恢复滚动位置
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!