一、概念
把一个组件当成另外一个组件的参数传入,然后通过一定的判断,返回新的组件。
二、基本用法
三、实战
例1:监听鼠标位置
App.js
import React from 'react'
import HOCDemo from './6.高级特性/4.HOCDemo'
function App() {
return (
<div>
<HOCDemo a='999' />
</div>
)
}
export default App
4.HOCDemo.js
import React from 'react'
// 高阶组件
const withMouse = (Component) => {
class withMouseComponent extends React.Component {
constructor(props) {
super(props)
this.state = { x: 0, y: 0 }
}
handleMouseMove = (event) => {
this.setState({
x: event.clientX,
y: event.clientY
})
}
render() {
return (
<div style={{ height: '500px', background: 'pink' }} onMouseMove={this.handleMouseMove}>
{/* 1. 透传所有 props (vue使用$props v-bind) 2. 增加 mouse 属性 */}
<Component {...this.props} mouse={this.state}/>
</div>
)
}
}
return withMouseComponent
}
const App = (props) => {
const a = props.a // 999
const { x, y } = props.mouse // 接收 mouse 属性
return (
<div style={{ height: '500px' }}>
<h1>The mouse position is ({x}, {y})</h1>
<p>{a}</p>
</div>
)
}
export default withMouse(App) // 返回高阶函数
例2:路由鉴权
App.js
// 导入路由
import { unstable_HistoryRouter as HistoryRouter, Routes, Route } from 'react-router-dom'
import { history } from './utils/history'
import './App.css'
import AuthRoute from './components/AuthRoute'
// 导入页面组件
// import Login from './pages/Login'
// import SysLayout from '@/pages/Layout'
// import Home from './pages/Home'
// import Article from './pages/Article'
// import Publish from './pages/Publish'
// 导入必要组件
import { lazy, Suspense } from 'react'
// 按需导入路由组件
const Login = lazy(() => import('./pages/Login'))
const SysLayout = lazy(() => import('@/pages/Layout'))
const Home = lazy(() => import('./pages/Home'))
const Article = lazy(() => import('./pages/Article'))
const Publish = lazy(() => import('./pages/Publish'))
// 配置路由规则
function App() {
return (
<HistoryRouter history={history}>
<Suspense
fallback={
<div
style={{
textAlign: 'center',
marginTop: 200
}}
>
loading...
</div>
}
>
<div className="App">
<Routes>
{/* 需要鉴权的路由 */}
<Route
path="/"
element={
<AuthRoute> // 高阶组件在这!!!!!!
<SysLayout/>
</AuthRoute>
}
>
<Route index element={<Home />}/>
<Route path="/article" element={<Article />} />
<Route path="/publish" element={<Publish />} />
</Route>
{/* 不需要鉴权的路由 */}
<Route path="/login" element={<Login/>} />
</Routes>
</div>
</Suspense>
</HistoryRouter>
)
}
export default App;
AuthRoute.js
// 1. 判断token是否存在
// 2. 如果存在 直接正常渲染
// 3. 如果不存在 重定向到登录路由
// 高阶组件: 把一个组件当成另外一个组件的参数传入 然后通过一定的判断 返回新的组件
import { getToken } from '@/utils'
import { Navigate } from 'react-router-dom'
function AuthRoute ({ children }) {
const isToken = getToken()
if (isToken) {
return <>{children}</>
} else {
return <Navigate to="/login" replace />
}
}
export default AuthRoute
// <AuthComponent> <Layout/> </AuthComponent>
// 登录:<><Layout/></>
// 非登录:<Navigate to="/login" replace />
具体请看我的项目
项目地址