注册网站模板,建设厅培训中心网站,wordpress 用户积分系统,最好的网页设计软件现在最新版本是Router6和Router5有比较大的变化#xff0c;Router5和Router4变化不大#xff0c;本文以Router6的写法为主#xff0c;也会对比和Router5的不同。比较全面。
安装路由
npm i react-router-dom基本使用
有两种Router#xff0c;BrowserRouter和HashRouterRouter5和Router4变化不大本文以Router6的写法为主也会对比和Router5的不同。比较全面。
安装路由
npm i react-router-dom基本使用
有两种RouterBrowserRouter和HashRouter选哪个都可以这里以HashRouter为例子BrowserRouter用法上没什么区别。
先给App组件套上一层Router这样就可以使用路由功能了。
import { BrowserRouter, HashRouter } from react-router-dom;root.render(React.StrictModeHashRouterApp //HashRouter/React.StrictMode
);
或者
root.render(React.StrictModeBrowserRouterApp //BrowserRouter/React.StrictMode
);在App里面我们需要定义一个Routes组件以及他的子组件RouteRoute会将path映射成对应的组件。也就是动态加载我们的Home或者About组件。
import { Routes, Route } from react-router-dom;
import Home from ./pages/Home;
import About from ./pages/About;function App() {return (div classNameAppdivHeader/divdivRoutesRoute path/home element{Home /} /Route path/about element{About /} //Routes/divdivFooter/div/div);
}export default App;Home和About就展示文本
import React from react;
class Home extends React.PureComponent {render() {return divHome Page/div;}
}
export default Home;在浏览器中输入路径注意我们使用的是HashRouter所以路径前面需要加#号。
http://localhost:3001/#/home效果就是Home组件的内容确实被动态加载了。
使用Link组件实现点击切换
上面的代码可以使用浏览器输入路径动态的切换内容。但一般用户不会直接在浏览器输入地址。一般我们会给个导航栏让用户点击这个功能用Link就可以很容易实现。
Link内容直接写显示的文本以及一个to属性用于指定路径和Route的path属性对应上就可以了。
import { Routes, Route, Link } from react-router-dom;
import Home from ./pages/Home;
import About from ./pages/About;function App() {return (div classNameAppdivLink to/home首页/LinkLink to/about关于/Link/divdivRoutesRoute path/home element{Home /} /Route path/about element{About /} //Routes/divdivFooter/div/div);
}export default App;这样就可以通过Link组件实现点击动态切换路由内容了。
404页面
当所有的路径都匹配不到的时候就匹配到了*。
Route path/home element{Home /} /
Route path/about element{About /} /
Route path/login element{Login /} /
Route path* element{NotFound /} /Link的一些额外属性
replace 是否重定向默认falsereloadDocument 是否出现加载文档会导致填的数据丢失,默认falsestate 可以传值在目标组件使用useLocation可以获取到值。
Link to/home replace{false} reloadDocument{false} state{{name:Tom}}NavLink的使用了解
NavLink可以使链接样式有一些变化。但实际上我们是很少使用的因为我们一般都自定义。作为了解就可以了。 当我们把Home组件的Link替换成NavLink的时候当Home组件的NavLink被点击的时候我们查看源代码发现a元素上面多了一个active的class。但NavLink被点击的时候我们可以通过这个active class来做一些样式上的变化。 我们直接定义一个class在组件里面引入在点击的时候就会触发这个效果了。
.active {color: red;font-size: 20px;
}支持下面的写法函数参数是arguments我们可以解构出isActive 这是这个组件提供的。 NavLinkto/homestyle{({ isActive }) ({ color: isActive ? red : green })}首页/NavLink也可以提供指定className的形式。 NavLinkto/aboutclassName{({ isActive }) (isActive ? linkActive : )}关于/NavLink这两个方式都可以简单的改变样式。
Navigate组件的使用
Navigate这个组件是用于重定向的。只要他被显示那么组件就会被重定向。可是实现登录跳转。 我们添加一个Login组件。并做路由配置。
实现登录跳转
import { Routes, Route, Link, NavLink } from react-router-dom;
import Home from ./pages/Home;
import About from ./pages/About;
import Login from ./pages/Login;
import ./pages/style.css;function App() {return (div classNameAppdivNavLinkto/homestyle{({ isActive }) ({ color: isActive ? red : green })}首页/NavLinkNavLinkto/aboutclassName{({ isActive }) (isActive ? linkActive : )}关于/NavLinkNavLinkto/loginclassName{({ isActive }) (isActive ? linkActive : )}登录/NavLink/divdivRoutesRoute path/home element{Home /} /Route path/about element{About /} /Route path/login element{Login /} //Routes/divdivFooter/div/div);
}export default App;
做一个条件判断只要满足条件我们就展示Navigate然后组件就会跳转到指定的路由。
import React from react;
import { Navigate } from react-router-dom;
class Login extends React.PureComponent {state {isLogin: false,};handleLogin() {this.setState({isLogin: true,});}render() {const { isLogin } this.state;return (divLogin Page{!isLogin ? (button onClick{(e) this.handleLogin()}登录/button) : (Navigate to/home /)}/div);}
}
export default Login;路径重定向
我们可以把/重定向到Home。 Route path/ element{Navigate to/home /} /路由嵌套
也就是二级路由这个是很常见的。也不难还是比较方便的。
需要给路由定义子路由。并且在路由是/home的时候重定向到/home/recommends这样可以避免第一次进来二级内容是空白的情况。 App.js RoutesRoute path/ element{Navigate to/home /} /Route path/home element{Navigate to/home/recommends /} /Route path/home element{Home /}Route path/home/recommends element{HomeRecommends /}/RouteRoute path/home/hots element{HomeHots /}/Route/Route/Routes在具体的页面设置Link组件并且放一个Outlet组件作为占位符。 divHome PagedivLink to/home/recommends推荐/LinkLink to/home/hots热门/LinkOutlet //div/div通过代码实现路由跳转
有时候我们需要通过代码实现路由跳转。在router6里面我们只能通过useNavigate这个hooks来实现代码路由跳转。用了hooks我们只能使用函数组件。如果一定要在类组件里面实现代码路由跳转我们只能自定义一个高阶函数withRouter(也是router6的写法)。
使用useNavigate hooks
虽然是通过代码实现路由跳转但Route还是要手动定义的这是跳转是通过代码实现的。 Route path/download element{Download /} /Route path/shop element{Shop /} /我们在原来的Link后面添加下面两个元素我们自己实现点击事件 button onClick{(e) handleNavigate(/download)}下载/buttonspan onClick{(e) handleNavigate(/shop)}商城/span使用useNavigate来实现跳转。这样就已经实现了通过代码实现路由跳转的功能了。
function App() {//这行必须写在函数外面const navigate useNavigate();function handleNavigate(path) {navigate(path);}return ...div...
}使用自定义实现高阶函数withRouter
这个自定义的高阶组件内部也是使用了useNavigate所以是router6才可以这么用。router5是自带一个withRouter函数的只是这个函数在router6被移除了。我们自己实现的这个只是叫withRouter这个名字内部实现是不一样的。
因为useNavigate只能在函数组件里面使用我们怎么在类组件里面也能用呢 就是使用高阶函数中间套一个函数组件并将navigate 放到props里面经过这个骚操作我们就可以在类组件的props里面获取到navigate了。
import { useNavigate } from react-router-dom;function withRouter(OriginComponent) {return function (props) {const navigate useNavigate();const router { navigate };// 套一个router对象因为可能会封装别的操作return OriginComponent {...props} router{router} /;};
}export default withRouter;这样我们就可以通过this.props获取到navigate了。
import React from react;
import withRouter from ../hoc/withRouter;
import { Outlet } from react-router-dom;
class Shop extends React.PureComponent {handleNavigate(path) {const { navigate } this.props.router;navigate(path);}render() {return (divShop Pagedivspan onClick{(e) this.handleNavigate(/shop/hots)}热卖/spanspan /spanspan onClick{(e) this.handleNavigate(/shop/offsale)}折扣/span/divOutlet //div);}
}
export default withRouter(Shop);App.js定义我们的Route。 Route path/shop element{Navigate to/shop/hots /} /Route path/shop element{Shop /}Route path/shop/hots element{ShopHots /} /Route path/shop/offsale element{ShopOffsale /} //Route效果就是点击商城再点击热卖或者折扣也可以切换路由。
路由参数传递 动态路由 查询字符
参数传递和动态路由
下面的形式是动态路由的形式我们可以根据传递的id来显示不同的页面。
Route path/shop/detail/:id element{ShopDetail /} /和获取navigate一样我们可以获取一个params那么这个params怎么来的呢我们需要在withRouter里面封装到props里面。
import React from react;
import withRouter from ../hoc/withRouter;
class ShopDetail extends React.PureComponent {render() {const { params } this.props.router;console.log(params);return divShopDetail id:{params.id}/div;}
}
export default withRouter(ShopDetail);这样我们就成功实现把params 封装到props里面了。
import { useNavigate, useParams } from react-router-dom;function withRouter(OriginComponent) {return function (props) {const navigate useNavigate();const params useParams();const router { navigate, params };return OriginComponent {...props} router{router} /;};
}export default withRouter;我们的事件发起源是下面这个地方通过navigate把含有id的路径传递给目标路由。
import React from react;
import withRouter from ./../hoc/withRouter;
class ShopHots extends React.PureComponent {state {goods: [{ id: 001, name: 商品1 },{ id: 002, name: 商品2 },{ id: 003, name: 商品3 },],};navigateToDetail(id) {console.log(id);const { navigate } this.props.router;navigate(/shop/detail/ id);}render() {const { goods } this.state;return (div商店热门divul{goods.map((item, index) {return (li onClick{(e) this.navigateToDetail(item.id)} key{index}{item.name}/li);})}/ul/div/div);}
}
export default withRouter(ShopHots);最后实现的效果如下 我们点击具体的商品跳转到商品详情页。
查询字符
我们给关于这个Link传点参数。 NavLinkto/about?usertomage18className{({ isActive }) (isActive ? linkActive : )}关于/NavLink在withRouter里面通过useSearchParams把query放到props里面。
import {useLocation,useNavigate,useParams,useSearchParams,
} from react-router-dom;function withRouter(OriginComponent) {return function (props) {const navigate useNavigate();const params useParams();// const location useLocation();// console.log(location:, location);const [searchParams] useSearchParams();const query Object.fromEntries(searchParams);const router { navigate, params, query };return OriginComponent {...props} router{router} /;};
}export default withRouter;最后在目标页面就可以通过props获取到query了。
import React from react;
import withRouter from ../hoc/withRouter;class About extends React.PureComponent {render() {const { query } this.props.router;return divAbout Page:{query.user query.age}/div;}
}
export default withRouter(About);路由配置
前面写的路由是通过Route组件来实现的router6提供了配置文件的形式估计是参考vue的本质上react是把配置文件还是转成我们上面写的Route组件的形式。
现在我们的Route是这些内容 divRoutesRoute path/ element{Navigate to/home /} /Route path/home element{Navigate to/home/recommends /} /Route path/home element{Home /}Route path/home/recommends element{HomeRecommends /}/RouteRoute path/home/hots element{HomeHots /}/Route/RouteRoute path/about element{About /} /Route path/login element{Login /} /Route path/download element{Download /} /Route path/shop element{Navigate to/shop/hots /} /Route path/shop/detail/:id element{ShopDetail /} /Route path/shop element{Shop /}Route path/shop/hots element{ShopHots /} /Route path/shop/offsale element{ShopOffsale /} //RouteRoute path* element{NotFound /} //Routes/div修改成下面的样子
import { Navigate } from react-router-dom;
import Home from ../pages/Home;
import About from ../pages/About;
import Login from ../pages/Login;
import NotFound from ../pages/NotFound;
import HomeHots from ../pages/HomeHots;
import HomeRecommends from ../pages/HomeRecommends;
import Download from ../pages/Download;
import Shop from ../pages/Shop;
import ShopHots from ../pages/ShopHots;
import ShopOffsale from ../pages/ShopOffsale;
import ShopDetail from ../pages/ShopDetail;
const routes [{path: /,element: Navigate to/home /,},{path: /home,element: Navigate to/home/recommends /,},{path: /home,element: Home /,children: [{path: /home/recommends,element: HomeRecommends /,},{path: /home/hots,element: HomeHots /,},],},{path: /about,element: About /,},{path: /login,element: Login /,},{path: /download,element: Download /,},{path: /shop,element: Navigate to/shop/hots /,},{path: /shop/detail/:id,element: ShopDetail /,},{path: /shop,element: Shop /,children: [{path: /shop/hots,element: ShopHots /,},{path: /shop/offsale,element: ShopOffsale /,},],},{path: *,element: NotFound /,},
];export default routes;
最后原来的位置提供useRoutes把routes传进去react就帮我们把配置文件解析好转成Route的形式了。
div{useRoutes(routes)}/div懒加载分包和Suspense
在不使用懒加载的情况下打包后的js内容全部打包到main这个js文件里面。 我们可以通过下面的语句对页面进行懒加载。import是webpack提供的特性。
const About React.lazy(() import(../pages/About));
const Home React.lazy(() import(../pages/Home));在使用懒加载后多出的js文件就是懒加载分包的js文件。 通常情况下在加载了懒加载之后页面会直接崩溃的但新版本react好像没有这个问题了如果崩溃需要添加Suspense可以有loading的效果当然fallback可以写空字符串用户就不会察觉到有loading。 Suspense fallbackloading...HashRouterApp //HashRouter/Suspense