vendredi 17 février 2023

Definig page component only by HOC in NextJS

I have nextjs (react) website I use (on every "page") same template - there is Detail and List component.

I have definition of every page as XML (not nextjs thing but my implementation). Root element here is Forms and childrens are individual form defined like this:

<Form FID="Event">
    <DetailFrame createNewEntryText="Add event">
        <Component attributeKey="img_url" componentName="chose file" componentType="FileChooser" path="img/albums/other/event-photos/@[img_url]"/>
        <Component attributeKey="title" componentName="Title" componentType="TextField" transformation="@[title]"/>
        <Component attributeKey="date" componentName="Date" componentType="DateField" transformation="@[date]"/>
        <Component attributeKey="description" componentName="Description" componentType="RichTextField" transformation="@[description]"/>
    </DetailFrame>
    <ListFrame orderBy="date" descending="true">
        <Component attributeKey="id_event" componentName="ID" componentType="TextField" transformation="@[id_event]"/>
        <Component attributeKey="img_url" componentName="Image preview" componentType="ImagePreview" transformation="img/albums/other/event-photos/@[img_url]" />
        <Component attributeKey="title" componentName="Title" componentType="TextField" transformation="@[title]"/>
        <Component attributeKey="date" componentName="Date" componentType="DateField" transformation="@[date]"/>
        <Component attributeKey="description" componentName="Description" componentType="RichTextField" transformation="@[description]"/>
    </ListFrame>
</Form>

Only thing what I need specify on every nextjs page is FID and individual component will then compose by their own by XML definition of form. All the stuff like menu and other components (except FormFrameContainer which is wrapper for Detail and List components) are defined in _document.tsx (= html wrapper for nextjs pages offered by nextjs) and _app.tsx (= components wrapper for nextjs pages offered by nextjs; wrapped by _document.tsx). To be clear - FormFrameContainer is wrapped by that stuffs in _app.tsx and _document.tsx.

So every administration page look almost same, like this:

const EventsPage: NextPage = (props: any) =>{
    const dispatch = useAppDispatch();
    
    useEffect(() => {
        dispatch({ type: SagaActions.SET_FORM_DEFINITIONS_AND_SET_FORM_BY_ID, FID: "Event" });
    }, [dispatch])

    return (
        <div>
            <FormFrameContainer />
        </div>
    )

}

Because of repetition I decided to move useeffect logic into hoc named withAdminPage:

export default (Page: NextPage, formID: string) => {    

    return (props) => {  
        const dispatch = useAppDispatch();
    
        useEffect(() => {
            dispatch({ type: SagaActions.SET_FORM_DEFINITIONS_AND_SET_FORM_BY_ID, FID: formID });
        }, [dispatch])

        return <Page {...props} />;
    }

}

So literaly the only thing what remains in particular pages is returning:

        <div>
            <FormFrameContainer />
        </div>

What comes to my mind is also move it to hoc, because it is also same in all pages => duplication. But it would mean, that I will not actually define components (my hoc will generate them) and in every page file will be only this one line:

export default withAdminPage(EventsPage, "Event");

For me it seems logic but also as some anitpattern to hoc (because hoc is defined as function, that take component and return new (enhanced) component). So? What would be best practise here? Would it be violation of some code standards?

Aucun commentaire:

Enregistrer un commentaire