第一步,首先需要创建一个react项目
creat-react-app router6
首先,删除app.js里的全部内容及app.css样式文件,创建一个自己的react-router6展示项目
操作完成页面展示如下
由于react官网实例全是用的函数式组件,且新推出的api也有往函数式组件靠的趋势,所以我们在这个案例中全部使用函数式组件,积极响应趋势。
src下新建pages文件夹存放页面文件,新建page1及page2页面
import React from 'react'
export default function Page1() {
return (
<div>我是page1页面</div>
)
}
在安装路由插件时无需指定版本,就会默认安装最新的react-router6版本了
npm i react-router-dom
为了使整个项目处于一个路由的管理下。我们将整个app组件用路由包起来,找到src下的index.js文件
import { BrowserRouter } from "react-router-dom";
ReactDOM.render(
<BrowserRouter>
<React.StrictMode>
<App />
</React.StrictMode>
</BrowserRouter>,
document.getElementById("root")
);
在路由链接的基本使用上,router6和router5并没有区别所以基本使用方法如下
<NavLink to='/page1'>去page1页面</NavLink>
<NavLink to='/page2'>去page2页面</NavLink>
在配置好了路由之后,很自然的需要配置路由组件的出口,在注册路由的使用上,router6摈弃了router5使用的switch而采用了routes,
router5写法
<Switch>
<route path='xxx' conponent='xxx'>
<route path='xxx' conponent='xxx'>
<route path='xxx' conponent='xxx'>
...
</Switch>
router6写法 亲测,这个地方不能使用组件的懒加载lazyLoad,只能使用一般引入,待后续填坑
import Page1 from "./pages/Page1";
import Page2 from "./pages/Page2";
<Routes>
<Route path="/page1" element={<Page1/>} />
<Route path="/page2" element={<Page2/>} />
</Routes>
在完成上例后,页面是已经能完成基本功能了的。但是在不点击路由链接时,控制台会出现一个警告
报错原因是没有匹配路径 " / " 的路由。对此我们需要将路径为 " / "的路径重定向到其他组件。
router5用法
<Redirect to='xxx路径'></Redirect>
router6用法
import { Navigate } from "react-router-dom";
<Route path="/" element={<Navigate to='/page1'/>} />
需要注意的是,Navigate一旦渲染,一定会引起页面执行。在page2页面编写代码如下
import React from "react";
import { useState } from "react";
import { Navigate } from "react-router-dom"
export default function Page2() {
const [count, setCount] = useState(0);
const changeCount = () => {
setCount(2);
};
return (
<div>
{count === 2 ? <Navigate to="/page1" /> : <span>count的值为{count}</span>}
<button onClick={changeCount}>点击我让state.count变成2</button>
</div>
);
}
很简单的小
page2中如果count不为2,那么显示count值,如果为2则跳转至page1页面
Navlink在选中的时候会自动添加上动态类名active
但在实际项目开发中,我们有时候并不想使用active类名。而是想用比如 ’ MyClass ’
router5
<NavLink activeClassName='MyClass' to='/page1'>去page1页面</NavLink>
router6新写法
<NavLink className={(isActive) => isActive ? 'MyClass' :" " } to='/page1'>去page1页面</NavLink>
<NavLink className={(isActive) => isActive ? 'MyClass' :" " } to='/page2'>去page2页面</NavLink>
重复的代码较多,实际开发一般封装成Navlink组件
可以看到route中 path和element都是一一对应的关系,所以实际开发中可以将route注册成路由表从外部引入方便管理
src下新建routes.js文件夹中新建index.js编辑如下
import Page1 from "../pages/Page1";
import Page2 from "../pages/Page2";
import { Navigate } from "react-router-dom";
const routesList = [
{
path: "/page1",
element: <Page1 />,
},
{
path: "/page2",
element: <Page2 />,
},
{
path: "/",
element: <Navigate to="/page1"></Navigate>,
},
];
export default routesList;
app.js中使用
import "./App.css";
import { NavLink, Route, Routes, Navigate, useRoutes } from "react-router-dom";
import routesList from "./Routes";
function App() {
const element = useRoutes(routesList)
return (
<div className="App">
react-router6展示项目
<div>
<NavLink to="/page1">去page1页面</NavLink>
<NavLink to="/page2">去page2页面</NavLink>
</div>
<div>{element}</div>
</div>
);
}
export default App;
tips:条条大路通罗马,学以至此发现vue和react大有互通之处,无论是先学react还是先学vue,再学另一个框架都会大有帮助
嵌套路由的使用与vue基本一模一样。首先新建一个组件作为page1的子路由
import React from 'react'
export default function Page1son() {
return (
<div>我是page1的子路由</div>
)
}
第二步,配置路由表
{
path: "/page1",
element: <Page1 />,
children:[{
path:'son',
element:<Page1son />
}]
},
第三步,在子组件中配置路由出口outlet
import React from 'react'
import { NavLink,Outlet } from 'react-router-dom'
export default function Page1() {
return (
<div>
<div>
<NavLink to='/page1/son'>去子路由</NavLink>
</div>
<div>
<Outlet />
</div>
</div>
)
}
截至目前,Navlink的作用就相当于vue中的router-link,outlet的作用就相当于router-view
此小节介绍路由传参的三种方式
params参数最大的特点,需要指定接收
路由注册页面index.js
传递参数
使用参数,在类式组件中可以通过this.props来获取params参数,而函数式组件中没有this,只能通过一个新的api—useParams。
import React from "react";
import { NavLink, Outlet, useParams } from "react-router-dom";
export default function Page1() {
const params = useParams();
console.log(params);
return (
<div>
<div>
<NavLink to="/page1/son">去子路由</NavLink>
</div>
<div>
<Outlet />
</div>
</div>
);
}
传递
<NavLink to="/page1/son">去子路由</NavLink>
使用,在router5中,取search参数还需要通过querystring来帮助解析,而在router6中,search参数被封装成了一个map对象
export default function Page1() {
const [search,setSearch] = useSearchParams();
console.log(search.get('id'));
return (
<div>
<div>
<NavLink to="/page1/son">去子路由</NavLink>
</div>
<div>
<Outlet />
</div>
</div>
);
}
传递
<NavLink to="/page1" state={{name:'wxs'}}>去page1页面</NavLink>
接收
const state = useLocation().state;
console.log(state);
此小结我们用编程式路由导航来实现page1页面的跳转
// 改写之前
{/* 去page1页面 */}
// 改写之后
const navigate = useNavigate()
const toPage1 = () => {
navigate('page1')
}
<button onClick={toPage1}>去page1页面</button>
params传参,同样的navLink里面怎么写,navigate里面就怎么写,search传参也是一样,如果是state传参那么就要用到第二个参数
const toPage1 = () => {
navigate('page1',{ state:xxx })
}