8

有人可以解释一下 React 中的高阶组件吗?我已经阅读并重新阅读了文档,但似乎无法更好地理解。根据文档,HOC 通过创建一个返回反应组件的主函数,通过向该函数传递参数来帮助消除重复。我对此有几个问题。

  • 如果 HOC 创建一个新的增强组件,是否可以根本不传入任何组件作为参数?
  • 在诸如this的示例中,它是高阶组件,theButtonEnhancedButton.
  • 我尝试像这样创建一个 HOC:

    // createSetup.js
    import React from 'react';
    
    export default function createSetup(options) {
        return class extends React.Component {
            constructor(props) {
                super(props);
    
                this.state = {};
    
                this.testFunction = this.testFunction.bind(this);
            }
    
            testFunction() {
                console.log("This is a test function");
            }
    
            render() {
                return <p>{options.name}</p>
            }
        }
    }
    
    
    // main.js
    import React from 'react';
    import {render} from 'react-dom';
    import createSetup from './createSetup';
    
    render((<div>{() => createSetup({name: 'name'})}</div>),
            document.getElementById('root'););
    

运行它不会显示 HOC,只会显示div

任何人都可以提供比给出的更好的例子吗?

4

4 回答 4

9

HOC 是一个函数,它将组件作为其参数之一,并以某种方式增强该组件。

如果 HOC 创建一个新的增强组件,是否可以根本不传入任何组件作为参数?

不,那么它就不是 HOC,因为其中一个条件是它们将组件作为参数之一,并且它们返回一个具有一些附加功能的新组件。

在这样的示例中,它是高阶组件,Button 或 EnhancedButton。

EnhanceButton是 HOC 并且FinalButton是增强组件。

我尝试像这样创建一个 HOC:...运行它不会显示 HOC,只显示 div

那是因为您的createSetup函数不是 HOC……它是一个返回组件的函数,是的,但它不会将组件作为参数来增强它。

让我们看一个基本 HOC 的示例:

const renderWhen = (condition, Component) =>
  props => condition(props)
    ? <Component {...props} />
    : null
);

你可以像这样使用它:

const EnhancedLink = renderWhen(({invisible}) => !invisible, 'a');

现在您EnhancedLink将像一个a组件,但是如果您将属性invisible集传递给true它,它将不会呈现......所以我们增强了a组件的默认行为,您可以使用任何其他组件来做到这一点。

在许多情况下,HOC 函数是 curried 并且 Component arg 放在最后......就像这样:

const renderWhen = condition => Component =>
  props => condition(props)
    ? <Component {...props} />
    : null
);

就像connectreact-redux 的功能一样......这使得组合更容易。看看重组

于 2017-08-29T11:29:54.230 回答
3

简而言之,如果你假设函数类似于组件,那么闭包类似于 HOC。

于 2018-08-13T19:45:42.393 回答
2

试试你的 createSetup.js:

const createSetup = options => <p>{options.name}</p>;

和你的 main.js

const comp = createSetup({ name: 'name' });
render((<div>{comp}</div>),
  document.getElementById('root'));
于 2017-08-29T10:08:57.160 回答
0

高阶组件 (HOC)是 React 中用于重用组件逻辑的高级技术。具体来说,高阶组件是一个接受一个组件并返回一个新组件的函数。

HOC 是一个具有零副作用的纯函数。

示例:条件渲染组件

假设我们有一个组件,只有在用户通过身份验证时才需要呈现——它是一个受保护的组件。我们可以创建一个名为WithAuth()的 HOC来包装该受保护的组件,然后在 HOC 中进行检查,如果用户已通过身份验证,它将仅呈现该特定组件。

根据上面的例子,一个基本的withAuth() HOC 可以写成如下:

// withAuth.js
import React from "react";
export function withAuth(Component) {
    return class AuthenticatedComponent extends React.Component {
        isAuthenticated() {
            return this.props.isAuthenticated;
        }

        /**
         * Render
         */
        render() {
            const loginErrorMessage = (
                <div>
                    Please <a href="/login">login</a> in order to view this part of the application.
                </div>
            );

            return (
                <div>
                    { this.isAuthenticated === true ? <Component {...this.props} /> : loginErrorMessage }
                </div>
            );
        }
    };
}

export default withAuth;

上面的代码是一个名为withAuth的 HOC 。它基本上接受一个组件并返回一个名为AuthenticatedComponent的新组件,用于检查用户是否经过身份验证。如果用户未通过身份验证,则返回loginErrorMessage组件;如果用户通过身份验证,则返回包装的组件。

注意:this.props.isAuthenticated 必须从应用程序的逻辑中设置。(或者使用 react-redux 从全局状态中检索它。)

为了在受保护的组件中使用我们的 HOC,我们可以这样使用它:

// MyProtectedComponent.js
import React from "react";
import {withAuth} from "./withAuth.js";

export class MyProectedComponent extends React.Component {
    /**
     * Render
     */
    render() {
        return (
            <div>
                This is only viewable  by authenticated users.
            </div>
        );
    }
}

// Now wrap MyPrivateComponent with the requireAuthentication function 
export default withAuth(MyPrivateComponent);

在这里,我们创建了一个只有经过身份验证的用户才能查看的组件。我们将该组件包装在withAuth HOC 中,以保护该组件免受未经身份验证的用户的攻击。

资源

于 2021-11-04T08:46:10.437 回答