Home > Enterprise >  Passing simple props to a react HOC
Passing simple props to a react HOC

Time:09-11

I’m trying make it so that, instead of doing this in my router:

<Route path='/about' element={<AboutPage />} />

I wrap the component in another <Page /> component, which needs to accept a meta prop. To clarify, the meta props are this type:

export type MetaTags = {
    title: string;
    description: string;
    [key: string]: any;
};

Doing the following works:

const aboutMeta = {
    title: 'About',
    description: 'About page description.',
};

<Route path='/about' element={<Page meta={aboutMeta}><AboutPage /></Page>} />

But it’s ugly and non-dynamic, and I don’t want to do this for every page in the router. I thought a HOC might be a better approach, so I could do something like this instead:

<Route path='/about' element={({metatags: aboutMeta}) => withPage(AboutPage)} />

But I do not know how to make the meta tag props available to the withPage component below:

const withPage = (Component: any) => (props: any) => {
    console.log('props: ', props); // how do you get the meta tags here?
    return (
        <Page meta={props.metatags}>
            <Component {...props} />
        </Page>
    );
};

const About = () => {
    const [test, setTest] = React.useState(false);

    return (
        <>
            <h1>About</h1>
            <p>Content...</p>
            <button onClick={() => setTest(!test)}>click</button>
        </>
    );
};

export const AboutPage = withPage(({ metatags: aboutMeta }: any) => About); // I also considered exporting the AboutPage component with withPage itself

Does anyone know what I’m doing wrong? Or alternatively, does anyone have a better solution that even using a HOC? I can’t seem to figure it out. Thank you

CodePudding user response:

You could probably do it like this.

const AboutPageWithMeta = () => withPage(About)({ metatags: aboutMeta });

<Route path='/about' element={<AboutPageWithMeta/>} />

but I dont really find it cleaner than

const AboutPage = withPage(About);
<Route path='/about' element={<AboutPage metatags={aboutMeta} />} />

CodePudding user response:

I think you need to pass the metatags this way:

<Route path='/about' element={() => withPage(AboutPage)({ metatags: aboutMeta })} />

Let's analyze:

withPage

const withPage = (Component: any) => (props: any) => {
    return (
        <Page meta={props.metatags}>
            <Component {...props} />
        </Page>
    );
};

running withPage(AboutPage) will return this:

(props: any) => {
    return (
        <Page meta={props.metatags}>
            <AboutPage {...props} />
        </Page>
    );
};

so basically if you want to pass the metatags to props, you can do this:

withPage(AboutPage)({ metatags: aboutMeta })
  • Related