认识高阶组件
- HOC:高阶组件 (Higher-Order Component),以组件作为参数,并返回一个组件;
- 通常,可以利用 HOC 实现横切关注点:
- eg1:有多个组件,每个组件在创建组件和销毁组件时,需要作日志记录;
- eg2:有多个组件,它们需要显示一些内容,得到的数据结构完全一致;
- …
高阶组件的使用案例
渲染判断鉴权
import React from 'react'
/**
* 高阶组件
* @param {*} comp 组件
*/
export default function withLogin(Comp) {
return function LoginWrapper(props) {
if (props.isLogin) {
return <Comp {...props} />
}
return null;
}
}
import React from 'react'
import withLogin from "./withLogin"
class A extends React.Component {
// 不再关注跟该组件不相关的事情
render() {
return <h1>A:{this.props.a}</h1>
}
}
let AComp = withLogin(A);
export default class App extends React.Component {
render() {
return (
<div>
<AComp isLogin a={1} />
</div>
)
}
}
生命周期劫持
import React from "react"
/**
* 高阶组件
* @param {*} comp 组件
*/
export default function withLog(Comp, str) {
return class LogWrapper extends React.Component {
componentDidMount() {
console.log(`日志:组件${Comp.name}被创建了!${Date.now()}`);
}
componentWillUnmount() {
console.log(`日志:组件${Comp.name}被销毁了!${Date.now()}`);
}
render() {
return (
<>
<h1>{str}</h1>
<Comp {...this.props} />
</>
)
}
}
}
import React from 'react'
import withLog from "./withLog";
class A extends React.Component {
// 不再关注跟该组件不相关的事情
render() {
return <h1>A:{this.props.a}</h1>
}
}
let AComp = withLog(A, "abc");
export default class App extends React.Component {
render() {
return (
<div>
<AComp a={1} />
</div>
)
}
}
注意
-
不要在 render 中生成高阶组件并使用;
export default class App extends React.Component { render() { // 会被重复创建和销毁 let AComp = withLogin(withLog(A, "abc")); return ( <div> <AComp isLogin a={1} /> <button onClick={() => { this.setState({}) }}>点击</button> </div> ) } }
-
不要在高阶组件内部更改传入的组件(限制了组件之后的扩展);
/** * 高阶组件 * @param {*} comp 组件 */ export default function withLog(Comp, str) { // 修改了传入组件的 componentDidMount Comp.prototype.componentDidMount = function() { } return class LogWrapper extends React.Component { componentDidMount() { console.log(`日志:组件${Comp.name}被创建了!${Date.now()}`); } componentWillUnmount() { console.log(`日志:组件${Comp.name}被销毁了!${Date.now()}`); } render() { return ( <> <h1>{str}</h1> <Comp {...this.props} /> </> ) } } }
高阶函数的意义
利用高阶组件可以针对某些 React 代码进行更加优雅的处理;
其实早期的 React 有提供组件之间的一种复用方式是 mixin,目前已经不再建议使用:
- Mixin 可能会相互依赖,相互耦合,不利于代码维护;
- 不同的 Mixin 中的方法可能会相互冲突;
- Mixin 非常多时,组件是可以感知到的,甚至还要为其做相关处理,这样会给代码造成滚雪球式的复杂性;
当然,HOC 也有自己的一些缺陷:
- HOC 需要在原组件上进行包裹或者嵌套,如果大量使用 HOC,将会产生非常多的嵌套,这让调试变得非常困难;
- HOC 可以劫持 props,在不遵守约定的情况下也可能造成冲突;
Hooks 的出现,是开创性的,它解决了很多 React 之前的存在的问题,比如 this 指向问题、比如 HOC 的嵌套复杂度问题等等;
React✍️ 组件通信---
上一篇