简体   繁体   中英

How to use generic types correctly in HOC components?

Here is my parent component (Grid), (here I pass more props used by hoc but I ommited them here):

<QuickBooksTable itemList={quickBooksList} />

Here is the table component:

export const QuickBooksTable = withIntegrationTable(props: : WithIntegrationTableChildProps & WithIntegrationTableProps) => ...

Here is the hoc:

export function withIntegrationTable<T extends WithIntegrationTableProps>(Component: React.ComponentType<T>) {
return (
    {
      itemList,
      ...props
    }: WithIntegrationTableProps & T
  ) => {
    const [state, setState] = useState<WithIntegrationTableState>({
      tableItems: new Array<any>(),
      selectedItems: new Set<string>(),
      isAllItemsSelected: false
    });

    useEffect(() => {
      const tableItems = mapItemList(itemList, currentUser);
      setState({
        ...state,
        tableItems
      });
    }, [itemList]);

    <Component {...props as T}
               tableState={state}
    />
  }
}

But when it compiles it says: Element QuickBooksTable doesn't have required attribute (here is another props name) . How should I use the types and generics to remove this error? I've tried to read the docs but I can't understand what I am doing wrong.

I think this is what you try to achieve.

import React from 'react';
import { useEffect, useState } from 'react';

interface WithIntegrationTableProps {
    itemList: string[]
}

interface WithIntegrationTableState { }

export const withIntegrationTable = <P extends WithIntegrationTableState>(
    Component: React.ComponentType<P & { 
        tableState: WithIntegrationTableState
    }>
): React.FC<P & WithIntegrationTableProps> => ({
    itemList,
    ...props
}: WithIntegrationTableProps) => {
    const mapItemList = (itemList: any, currentUser: any) => {

    }

    const [state, setState] = useState<WithIntegrationTableState>({
        tableItems: new Array<any>(),
        selectedItems: new Set<string>(),
        isAllItemsSelected: false
    });

    useEffect(() => {
        const tableItems = mapItemList(itemList, null);
        setState({
            ...state,
            tableItems
        });
    }, [itemList]);

    return <Component {...props as P} tableState={state} />
}

export const QuickBooksTable = withIntegrationTable(({ ...props }) => {
    console.log(props.tableState)
    return <div>
        test
    </div>
})

const App = () => {
    return <QuickBooksTable itemList={[]} />
}

export default App

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM