Search K
Appearance
Appearance
npm install react-router-dom
这里假设登录界面有一个isLogin
字段,如果为ture
则自动跳转到首页,否则则显示登录文字
示例代码:
import React, {Component} from 'react';
import {Navigate} from "react-router-dom";
class Login extends Component {
constructor() {
super();
this.state = {
isLogin: false
}
}
login() {
this.setState({isLogin: true});
}
render() {
const {isLogin} = this.state;
const element = isLogin ? <Navigate to="/"/> : <button onClick={() => {
this.login()
}}>登录</button>
return (
<div>
<h2>登录页面</h2>
{element}
</div>
);
}
}
Login.propTypes = {};
export default Login;
Navigate
其中一个应用:
这样匹配/
可以重定向到/home
路由
<Routes>
<Route path='/' element={<Navigate to="/home"/>}/>
<Route path='/home' element={<Home/>}/>
</Routes>
官方推荐使用useNavigate
,但是useNavigate
只能用于函数式组件中
示例代码:
import { Route, Routes, useNavigate} from "react-router-dom";
import Home from "./pages/Home";
import About from "./pages/About";
import Profile from "./pages/Profile";
import classNames from "classnames";
import Login from "./pages/Login";
import NotFound from "./pages/NotFound";
import HomeRecomend from "./pages/HomeRecomend";
function App() {
// hooks只能放在最上面
const navigate = useNavigate()
function navigateTo(url) {
navigate(url)
}
return (
<div className="App">
<div style={{display: "flex", justifyContent: "space-around"}}>
<button onClick={() => { navigateTo("/profile") }}>点击跳转我的</button>
</div>
<Routes>
<Route path='/' element={<Navigate to="/home"/>}/>
<Route path='/profile' element={<Profile/>}/>
</Routes>
</div>
);
}
export default App;
类组件如果想要使用navigate
对象,可以封装一个高阶函数对其扩展
示例代码:
src/hoc/withRouter.jsx
import {useNavigate} from "react-router-dom";
export default function withRouter(WrapperComponent) {
return props => {
const navigate = useNavigate();
return <WrapperComponent {...props} router={navigate}/>;
}
}
页面中使用: Profile.jsx
import React, {Component} from 'react';
import withRouter from "../hoc/withRouter";
class Profile extends Component {
render() {
return (
<div>
<h2>profile</h2>
<button onClick={ () => { this.props.router('/home') } }>点击跳转首页</button>
</div>
);
}
}
Profile.propTypes = {};
export default withRouter(Profile);
路由配置
<Routes>
<Route path='/profile/:id' element={<Profile/>}/>
</Routes>
跳转方式
<NavLink to="/profile/123">我的</NavLink>
function navigateTo(url) {
navigate(url)
}
<button onClick={ () => { navigateTo("/profile/4" ) } }>点击跳转我的</button>
如何获取参数,可以利用useParams
hooks
获取路由参数
扩展withRouter
,传入useParams
src/hoc/withRouter.jsx
import {useNavigate, useParams} from "react-router-dom";
export default function withRouter(WrapperComponent) {
return props => {
const navigate = useNavigate();
const params = useParams();
const router = { navigate,params }
return <WrapperComponent {...props} router={router}/>;
}
}
页面中获取参数
import React, {Component} from 'react';
import withRouter from "../hoc/withRouter";
class Profile extends Component {
render() {
return (
<div>
<h2>profile</h2>
<button onClick={ () => { this.props.router.navigate('/home') } }>点击跳转首页</button>
<h2>当前参数:</h2>
<div> { JSON.stringify(this.props.router) } </div>
</div>
);
}
}
export default withRouter(Profile);
跳转
<NavLink to="/about?name=zhangsan&age=18" className={getActiveClass}>关于</NavLink>
如何获取参数,扩展withRouter
import {useNavigate, useParams, useSearchParams} from "react-router-dom";
export default function withRouter(WrapperComponent) {
return props => {
const navigate = useNavigate();
const params = useParams();
const [searchParams] = useSearchParams()
// 将URLSearchParams转化为一个普通对象
const query = Object.fromEntries(searchParams)
const router = { navigate,params,query }
return <WrapperComponent {...props} router={router}/>;
}
}
获取参数 About.js
import React, {Component} from 'react';
import withRouter from "../hoc/withRouter";
class About extends Component {
render() {
return (
<div>
<h2>About</h2>
<h2>当前参数:</h2>
<div> {JSON.stringify(this.props.router)} </div>
</div>
);
}
}
export default withRouter(About);
src/router/index.js
import {Navigate} from "react-router-dom";
import Home from "../pages/Home";
import HomeRecomend from "../pages/HomeRecomend";
import About from "../pages/About";
import Profile from "../pages/Profile";
import Login from "../pages/Login";
import NotFound from "../pages/NotFound";
export const routes = [
{
path: "/",
element: <Navigate to="/home"/>
},
{
path: "/home",
element: <Home/>,
children: [
{
path: "/home",
element: <Navigate to="/home/recomend"/>
},
{
path: "/home/recomend",
element: <HomeRecomend/>
}
]
},
{
path: "/about",
element: <About/>
},
{
path: "/profile/:id",
element: <Profile/>
},
{
path: "/login",
element: <Login/>
},
{
path: "*",
element: <NotFound/>
}
]
App.js
import {useRoutes} from "react-router-dom";
import {routes} from "./router";
function App() {
return (
<div className="App">
<div>
{ useRoutes(routes) }
</div>
{/* 以下代码可以省略 */}
{/*<Routes>*/}
{/* <Route path='/' element={<Navigate to="/home"/>}/>*/}
{/* <Route path='/home' element={<Home/>}>*/}
{/* <Route path="/home" element={<Navigate to="/home/recomend"/>}></Route>*/}
{/* <Route path="/home/recomend" element={<HomeRecomend/>}></Route>*/}
{/* </Route>*/}
{/* <Route path='/about' element={<About/>}/>*/}
{/* <Route path='/profile/:id' element={<Profile/>}/>*/}
{/* <Route path='/login' element={<Login/>}/>*/}
{/* <Route path="*" element={<NotFound/>}></Route>*/}
{/*</Routes>*/}
</div>
);
}
export default App;
现在的配置最终经过Webpack
打包后只会形成一个main.js
文件,对其分包(懒加载)以后就可以形成单个js
文件,分包后会形成多个xxxx.chunk.js
文件
src/router/index.js
import NotFound from "../pages/NotFound";
import React from "react";
const About = React.lazy(() => import("../pages/About"));
const Login = React.lazy(() => import("../pages/Login"));
export const routes = [
{
path: "/about",
element: <About/>
},
{
path: "/login",
element: <Login/>
},
{
path: "*",
element: <NotFound/>
}
]
要使用懒加载项目入口js
需要使用Suspense
组件进行包裹
import React, {Suspense} from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import {HashRouter} from "react-router-dom";
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Suspense fallback={ <div>loading</div> }>
<HashRouter>
<App/>
</HashRouter>
</Suspense>
</React.StrictMode>
);