什么是高阶函数
- 高阶函数的维基百科定义:至少满足以下条件之一:
- 接受一个或多个函数作为输入;
- 输出一个函数:
高阶组件 ★★★
高阶组件(higherOrderComponent简称(HOC))是 React 中用于复用组件逻辑的一种高级技巧:是一种基于 React 的组合特性而形成的设计模式
高阶组件是参数为组件,返回值为新组件的函数。 组件是将 props 转换为 UI,而高阶组件是将组件转换为另一个新组件。其实是对新组件进行了一次拦截
import React, { PureComponent } from 'react'
function hoc(WrappedComponent) {
// 定义 类组件进行拦截操作
class NewWrappedComponent extends PureComponent {
render() {
return (
<div>
<WrappedComponent name="我是拦截后新增的数据" />
</div>
)
}
}
return NewWrappedComponent
}
// 这里定义常用组件
class Son extends PureComponent {
render() {
const { name } = this.props
return (
<div>显示Son组件,我是参数props:{name}</div>
)
}
}
// 使用高阶函数,实际对Son组件进行拦截操作内容数据
const ComHOC = hoc(Son)
export class App extends PureComponent {
render() {
return (
<div>
{/* 默认用法 */}
<h1><Son/></h1>
{/* 高阶组件 */}
<ComHOC />
</div>
)
}
}
export default App
应用示例
import React, { PureComponent } from 'react'
// 高阶组件这里可以抽取出去作为Hook使用为了方便没有抽取直接观察理解
function higherOrderComponent(OldCompon){
class NewCom extends PureComponent{
constructor(props){
super(props)
this.state={
info:{
name:"林夕",
age:18
}
}
}
render(){
return(
<OldCompon {...this.props} {...this.state.info}/>
)
}
}
return NewCom
}
const Header=higherOrderComponent(function(props) {
return (
<div>
<h1>Header :{props.name}-{props.age} </h1>
<h1>主动传输 :{props.topName} </h1>
</div>
)
})
export class App extends PureComponent {
render() {
return (
<div>
<Header/>
<Header topName="我是主动传输参数"/>
</div>
)
}
}
export default App
搭配Context使用
import React, { createContext, PureComponent } from 'react'
const ThemeContext = createContext()
//可以作为单独js库进行拆分
function withTheme(Com) {
return (props) => {
return (
<ThemeContext.Consumer>
{
value => {
return <Com {...value} {...props}></Com>
}
}
</ThemeContext.Consumer>
)
}
}
// 子组件内容
class Comson extends PureComponent {
render() {
const { name, age } = this.props
return (
<div>
<h1>{name}-{age}</h1>
</div>
)
}
}
const Son = withTheme(Comson)
// 父组件
export class App extends PureComponent {
render() {
return (
<div>
<ThemeContext.Provider value={{ name: "林夕", age: 18 }}>
<Son />
</ThemeContext.Provider>
</div>
)
}
}
export default App
搭配登录进行高阶组件
import React, { PureComponent } from 'react'
// 作为登录拦截操作
function loginCheck(WrappedComponent) {
return (props) => {
const login = localStorage.getItem("login")
if (login) {
return <WrappedComponent />
} else {
return <h1>暂未登录</h1>
}
}
}
// 组件使用
class SonComponent extends PureComponent {
render() {
return (
<div>SonComponent</div>
)
}
}
// 高阶组件使用
const SonComp = loginCheck(SonComponent)
export class App extends PureComponent {
constructor() {
super()
this.state = {
isLogin: false
}
}
login() {
const { isLogin } = this.state
const loginToken = localStorage.getItem("login")
if (loginToken && isLogin) {
localStorage.removeItem("login")
} else {
localStorage.setItem("login", true)
}
this.setState((state) => ({ isLogin: !state.isLogin }))
// 如果你不想使用state而进行改变内容可以使用
// this.forceUpdate()
}
render() {
const { isLogin } = this.state
return (
<div>
App
<button onClick={e => this.login()}>{isLogin ? '退出登录' : '点击登录'}</button>
<SonComp />
</div>
)
}
}
export default App
缺点
- HOC需要在原组件上进行包裹或者嵌套,如果大量使用HOC,将会产生非常多的嵌套,调试起来非常困难;
- HOC可以劫持props,在不遵守约定的情况下也可能造成冲突:
- 例如钻进传输一个名为name的属性,但是HOC可能重新定义name属性造成覆盖