关于react.js:React的高阶组件怎么用

一、高阶组件是什么?

高阶组件(HOC)是一个接管组件作为参数并返回新组件的函数。将多个组件的雷同逻辑代码,形象到HOC中,让组件更有结构化,更易于复用。HOC不毁坏传入组件的个性,只通过组合造成新组件。HOC是纯函数,没有副作用。


二、高阶组件实例

承受了组件WrappedComponent,减少了订阅和数据刷新的操作。

// 此函数接管一个组件...
function withSubscription(WrappedComponent, selectData) {
    // ...并返回另一个组件...
    return class extends React.Component {
        constructor(props) {
            super(props);
            this.handleChange = this.handleChange.bind(this);
            this.state = {
                data: selectData(DataSource, props)
            };
        }

        componentDidMount() {
            // ...负责订阅相干的操作...
            DataSource.addChangeListener(this.handleChange);
        }

        componentWillUnmount() {
            DataSource.removeChangeListener(this.handleChange);
        }

        handleChange() {
            this.setState({
                data: selectData(DataSource, this.props)
            });
        }

        render() {
            // ... 并应用新数据渲染被包装的组件!
            // 请留神,咱们可能还会传递其余属性
            return <WrappedComponent data={this.state.data} {...this.props} />;
        }
    };
}

想要减少订阅和数据刷新性能的组件,都能够应用withSubscription,调用如下:

const CommentListWithSubscription = withSubscription(
    CommentList,
    (DataSource) => DataSource.getComments()
);

const BlogPostWithSubscription = withSubscription(
    BlogPost,
    (DataSource, props) => DataSource.getBlogPost(props.id)
);

三、只组合,不毁坏原组件
1、谬误:曾经毁坏
function logProps(InputComponent) {
    InputComponent.prototype.componentDidUpdate = function (prevProps) {
        console.log('Current props: ', this.props);
        console.log('Previous props: ', prevProps);
    };
    // 返回原始的 input 组件,暗示它曾经被批改。
    return InputComponent;
}

// 每次调用 logProps 时,加强组件都会有 log 输入。
const EnhancedComponent = logProps(InputComponent);
2、正确:组合组件
function logProps(WrappedComponent) {
    return class extends React.Component {
        componentDidUpdate(prevProps) {
            console.log('Current props: ', this.props);
            console.log('Previous props: ', prevProps);
        }
        render() {
            // 将 input 组件包装在容器中,而不对其进行批改。Good!
            return <WrappedComponent {...this.props} />;
        }
    }
}

四、类似接口

HOC 返回的组件与原组件应放弃相似的接口。

render() {
    const { extraProp, ...passThroughProps } = this.props;
    const injectedProp = someStateOrInstanceMethod;
    return (
        <WrappedComponent
            injectedProp={injectedProp}
            {...passThroughProps}
        />
    );
}

五、HOC不便调试

用HOC包裹组件,加上HOC和组件的名字,调试时输入,不便精确定位bug地位。

function withSubscription(WrappedComponent) {
    class WithSubscription extends React.Component {/* ... */ }
    WithSubscription.displayName = `WithSubscription(${getDisplayName(WrappedComponent)})`;
    return WithSubscription;
}

function getDisplayName(WrappedComponent) {
    return WrappedComponent.displayName || WrappedComponent.name || 'Component';
}
六、render()中禁止应用HOC

在render办法中应用HOC,每一次HOC都会产生一个新组件,使得原来组件被卸载,再从新加载新组件,这不仅仅是性能问题 – 从新挂载组件会导致该组件及其所有子组件的状态失落。

render() {
    // 每次调用 render 函数都会创立一个新的 EnhancedComponent
    // EnhancedComponent1 !== EnhancedComponent2
    const EnhancedComponent = enhance(MyComponent);
    // 这将导致子树每次渲染都会进行卸载,和从新挂载的操作!
    return <EnhancedComponent />;
}

七、静态方法与HOC

用HOC包裹原组件,造成新组件,将不能拜访原始组件的静态方法。

// 定义动态函数
WrappedComponent.staticMethod = function() {/*...*/}
// 当初应用 HOC
const EnhancedComponent = enhance(WrappedComponent);

// 加强组件没有 staticMethod
typeof EnhancedComponent.staticMethod === 'undefined' // true

能够通过上面这个计划解决:

// 应用这种形式代替...
MyComponent.someFunction = someFunction;
export default MyComponent;

// ...独自导出该办法...
export { someFunction };

// ...并在要应用的组件中,import 它们
import MyComponent, { someFunction } from './MyComponent.js';

八、参考链接:
  • React的高阶组件怎么用?

【腾讯云】轻量 2核2G4M,首年65元

阿里云限时活动-云数据库 RDS MySQL  1核2G配置 1.88/月 速抢

本文由乐趣区整理发布,转载请注明出处,谢谢。

您可能还喜欢...

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据