繁体   English   中英

反应-应该将高阶组件编写为函数吗?

[英]React - should Higher Order Component be written as a function?

我正在学习React。 在我看来,HOC就像来自React官方文档的以下示例:

function withSubscription(WrappedComponent, selectData) {
    // ...and returns another component...
    return class extends React.Component {
        constructor(props) {
            super(props);
            this.handleChange = this.handleChange.bind(this);
            this.state = {
                data: selectData(DataSource, props)
            };
        }

        componentDidMount() {
            // ... that takes care of the subscription...
            DataSource.addChangeListener(this.handleChange);
        }

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

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

        render() {
            // ... and renders the wrapped component with the fresh data!
            // Notice that we pass through any additional props
            return <WrappedComponent data={this.state.data} {...this.props} />;
        }
    };
}

可以这样重写:

class WithSubscription extends React.Component {
    constructor({ component, selectData, ...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 <component data={this.state.data} {...this.props} />;
    }
}

然后像这样使用它:

<WithSubscription component={BlogPost} selectData={(DataSource) => DataSource.getComments()} />

他们都是HOC吗? 什么时候一种风格比另一种更好?

一开始,我也在HOC方面挣扎。 另一种查看方式是组件包装,您可以使用这些组件将功能与一个组件隔离。

例如,我有多个HOC。 我有许多仅由props定义的组件,一旦创建,它们是不可变的。

然后,我有一个Loader HOC组件,该组件处理所有网络连接,然后将道具传递给要包装的任何组件(这就是您传递给HOC的组件)。

加载程序并不真正在乎它正在渲染哪个组件,它只需要获取数据并将其传递给包装的组件。

在您的示例中,您实际上可以完成此操作,但是一旦您需要链接多个HOC,它将变得更加复杂。

例如,我有此HOC链:

PermissionsHOC-> LoaderHOC-> BorderLayoutHOC-> Component

第一个可以检查您的权限,第二个可以加载数据,第三个可以提供通用布局,第四个是实际组件。

如果您意识到某些组件将从父级上的通用逻辑中受益,则检测HOC会容易得多。 您可以在示例中执行相同的操作,但是每次添加子组件时都需要修改HOC,以添加该子组件的逻辑。 不是很有效。 这样,您可以轻松添加新组件。 我确实有一个Base组件,每个组件都可以扩展,但是我用它来处理诸如分析,记录器,处理错误等辅助功能。

他们所谓的“ HOC”基本上是一个功能类似于组件工厂的函数(只是一个常规函数,不是特定于React的)。 这意味着它会输出包装的组件,这些组件是包装您选择的任何内部组件的结果 您的选择由“ WrappedComponent”参数指定。 (请注意,他们所谓的“ HOC”实际上是如何返回一个类的)。

所以我不知道为什么他们称其为“ HOC” TBH。 它只是一个吐出组件的函数。 如果有人知道为什么我会对听到这个原因感兴趣。

从本质上讲,他们的示例确实在执行您的操作,但是它更灵活,因为WrappedComponent被作为参数使用。 因此,您可以指定任何内容。

另一方面,您的代码将内部组件硬编码到其中。

为了查看他们的示例的强大功能,假设您有一个名为insideComp.js的文件,其中包含:

import withSubscription from './withSubscription';

class InsideComp extends React.Component{
// define it
}

export default withSubscription(InsideComp);

当您在另一个文件中使用insideComp时:

import myComp from './insideComp.js';

您实际上不是在导入insideComp,而是在导入“ withSubscription”已经包装好的版本。 因为请记住您的insideComp.js最后一行是

export default withSubscription(InsideComp);

因此,您的InsideComp在导出之前已被修改

第二个不是HOC。

他们从高阶函数中创造了HOC一词。 高阶函数的一个示例是将函数作为参数并返回另一个函数的函数。

类似地,HOC是将一个组件作为参数并返回另一个组件的函数。

这对我来说确实很奇怪,因为高阶分量不是反应分量。 它是一个函数。 我猜他们称其为HOC的原因是:

React组件是一个类,它实际上是JavaScript中的构造函数(除了功能组件只是函数)。 HOC实际上需要一个函数(一个构造函数)并返回另一个函数(另一个构造函数),因此,考虑一下它实际上是一个高阶函数。 可能是因为它在react上下文中,并且这是转换组件的一种模式,因此他们将其称为HOC。

关于您提到的两种样式之间的区别:

第一个:您将使用第一个生成类似MyComponnet = withSubscription(AnotherComponent, ...) ,只要在渲染调用中需要它,只需编写<MyComponent><MyComponent>

第二个:这不太常见。 每次在渲染调用中需要它时,都需要包含描述中所述的<WithSubscription component={BlogPost} selectData={(DataSource) => DataSource.getComments()} />

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM