reactjsreact-hooksreact-typescriptreact-custom-hookshigh-order-component

Can't use hook inside Higher order component


I want to use a useState hook inside my HOC, but that prevents the component from being rendered

here is my component

import WithAccessControl from "components/HOC/AccessControl";

function GoalPage(props: any) {
    return <div>Who stole my goals?</div>;
}
export default WithAccessControl(GoalPage);

and this is my HOC which the component is passed to:

import React from "react";

const WithAccessControl = (Component: React.FC) => {
    debugger;
    [state, setState] = React.useState();
    return Component;
};

export default WithAccessControl;

When I don't use useState() inside my HOC, It works fine, but after adding so, It just doesn't render without any console errors, and after adding a debugger to the code I noticed that the webpack is throwing an error.


This is how webpack throws the error from debugger :

__webpack_require__.i.push((options) => {
    const originalFactory = options.factory;
    options.factory = function (moduleObject, moduleExports, webpackRequire) {
        __webpack_require__.$Refresh$.setup(options.id);
        try {
            originalFactory.call(this, moduleObject, moduleExports, webpackRequire);
        } finally {
            if (typeof Promise !== 'undefined' && moduleObject.exports instanceof Promise) {
                options.module.exports = options.module.exports.then(
                    (result) => {
                        __webpack_require__.$Refresh$.cleanup(options.id);
                        return result;
                    },
                    (reason) => {
                        __webpack_require__.$Refresh$.cleanup(options.id);
                        return Promise.reject(reason);
                    }
                );
            } else {
                __webpack_require__.$Refresh$.cleanup(options.id)
            }
        }
    };
})

what is causing the error and WHY?


Solution

  • Well you cannot use a hook in normal functions, only in components. Your HOC is not a component, but a wrapper method that returns a component.

    What you want would be something like (simple version)

    import React from "react";
    
    const WithAccessControl = (Component: React.FC) => {
        debugger;
        return (props) => {
          const [state, setState] = React.useState();
          
          return <Component {...props} />;
        }
    };
    
    export default WithAccessControl;