Open Joyeuxman opened 5 years ago
补充代码
var enhanceComponent = (Component) => {
class Enhance extends React.Component {
render() {
return (
<Component {...this.props} />
)
}
}
}
var OriginalTitle = () => <h1>Hello World</h1>;
var EnhancedTitle = enhanceComponent(OriginalTitle);
class App extends React.Component {
render() {
return <EnhancedTitle />;
}
}
// 高阶组件的主要功能主要是封装并抽离组件的通用逻辑
function getDisplayName(component) {
return component.displayName || component.name || 'Component';
}
export default function withHeader(title = 'title') {
return function (WrappedComponent) {
return class HOC extends React.Component {
static displayName = `HOC(${getDisplayName(WrappedComponent)})`;
render() {
return (
<div>
<div>
{title}
</div>
<WrappedComponent {...this.props} />
</div>
)
}
}
}
}
@withHeader('Demo') //相当于 const enhanceDemo = withHeader('Demo')(Demo)
export default class Demo extends React.Component {
render() {
return (
<div>
我是一个普通组件
</div>
)
}
}
// 基于属性代理的方式
// this 指向谁 HOC
export default function withHeader(WrappedComponent) {
return class Hoc extends React.Component {
render() {
const newProps = {
test: 'hoc',
}
return (
<WrappedComponent {...this.props} {...newProps} />
)
}
}
}
// 基于反向继承的方式
export default function (WrappedComponent) {
return class Inheritance extends WrappedComponent {
componentDidMount() {
console.log(this.state);
}
render() {
return super.render();
}
}
}
// 基于反向继承的方式实现一个loading组件
import React, { Component } from 'react';
import { spin } from 'antd';
export default function withLoading(loadingCheck) {
return function (WrappedComponent) {
return class extends WrappedComponent {
componentWillUpdate(nextProps, nextState) {
console.log('更新之前');
}
render() {
if (loadingCheck(this.props)) {
return <Spin tip="加载中" size="large">
{super.render()}
</Spin>
} else {
return super.render();
}
}
}
}
}
// @withLoading(props => {
// return props.IndexStore.accountList.length === 0;
// })
// 基于属性代理的方式实现Copy高阶组件
import React, { Component } from 'react';
import ReactDom from 'react-dom';
import { message } from 'antd';
import gotem from 'gotem';
export default copy = (targetName) => {
return (WrappedComponent) =>{
return class extends Component{
componentDidMount(){
const ctx = this;
const dom = ReactDom.findDOMNOde(ctx);
const nodes = {
trigget:dom,
target:dom.querySelect(targetName),
}
gotem(nodes.trigger,nodes.target,{
success:function(){
message.success('复制成功');
},
error:function(){
message.error('复制失败,请手动输入');
}
})
}
render(){
return(
<WrappedComponent {...this.props} />
)
}
}
}
}
@copy('h3')
class Info extends Component{
render(){
return(
<div>
<h3>
阿西吧,点击复制文字
</h3>
</div>
)
}
}
概念
高阶组件的使用场景
实现高阶组件的方式
属性代理(props-proxy)
属性代理:通过做一些操作,将被包裹组件(Demo)的
props
()和新生成的props
一起传递给此组件。示例:
总结:withHeader是一个高阶函数,接受Demo组件,返回一个增强的Demo组件。本示例中,增加了一个标题,同时,增强了属性。 在Demo组件类实例化后的this中,其props属性中含有desc_0(来自增强组件)、desc_1(来自包裹组件自身),当被包裹组件和增强组价的属性名称相同时,包裹组件的属性会覆盖掉增强组件的同名属性。
反向继承(inheritance inversion)