Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Problem with wrapping whole React App (all pages) in certain functionality

I have React App consisting of few pages. LandingPage (to be clear, it is really the first page in app flow)is like this:

export const LocalLandingPage = () => {
    const { Favorites } = useFavorites();
    React.useEffect(() => {
        Favorites.manageSupport() && Favorites.showSize();
    }, []);

    return (...here goes actual content...);
};

const LandingPage = withRouter(wrappedInLinkToSearchHOC(WithSnackBarHOC(LocalLandingPage)));

Here I call hook useFavorites which gathers some methods dealing with a specific subset of local Storage content(and dispatches actions to Redux store as well). The code above return call is checks support for local Storage and tells if some specific items are stored and in what quantity.
The story is that I have realized that if someone enters not the LandingPage but any other page of the app, the code will not be executed and support for localStorage not checked.
Besides, it is really not LandingPage business to deal with storage, so it should be removed anywhere.

My idea was to write HOC and wrap the application. So, here is this HOC (to keep things simple it is initially JS not TS) To make useFavorites work, it had to be a hook, too.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import useFavorites from '../hooks/useFavorites';

const useCheckSupportForLocalStorage = Component => {
    const { Favorites } = useFavorites();
    // React.useEffect(() => {
    Favorites.manageSupport() && Favorites.showSize();
    // }, []);

    return props => <Component {...props} />;
};

export default useCheckSupportForLocalStorage;

Having it done, I have tried to use it on App like this

function App() {
    return (
        <Switch>
            ... here are routes...
        </Switch>
    );
}
export default useCheckSupportForLocalStorage(App);

It throws an error:

React Hook "useCheckSupportForLocalStorage" cannot be called at the top level.

That is truth, no doubt. So, the next idea was to create a temporary component from all routes.

function Routes() {
    const Routes = useCheckSupportForLocalStorage(
        <>
            <Route exact path={Paths.landing} component={Awaiting(StarWars)} />
            ...here is the rest or outes...
        </>,
    );
    return <Routes />;
}
export default Routes;

And use it in rewritten App like this

function App() {
    return (
        <Switch>
            <Routes />
        </Switch>
    );
}

but it throws error

Routes’ cannot be used as a JSX component.
Its return type ‘(props: any) => Element’ is not a valid JSX element.
Type ‘(props: any) => Element’ is missing the following properties from type ‘ReactElement<any, any>’: type, props, key

Forcing useCheckSupportForLocalStorage th have return type of ReactElement doesn’t help, just leads to other error. I have checked few others options as well. What is wrong, how should it be written?
Basically I could stop using useFavorites in this hook, then it would be just a function – but it would be extreme headache.

>Solution :

You say

To make useFavorites work, it had to be a hook, too.

That is not true, since you have it in a component it will work just fine. And my understanding is that you want to wrap your whole app with it, so no need for the HOC. Just use it at the top of your app hierarchy.

something like

import useFavorites from '../hooks/useFavorites';

const CheckSupportForLocalStorage = ({ children }) => {
    const { Favorites } = useFavorites();
    React.useEffect(() => {
        Favorites.manageSupport() && Favorites.showSize();
    }, []);

    return children;
};

export default CheckSupportForLocalStorage;

and

function App() {
    return (
      <CheckSupportForLocalStorage>
        <Switch>
            ... here are routes...
        </Switch>
      </CheckSupportForLocalStorage>
    );
}
export default App;
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading