How to use Props with Generics with React.memo

前端 未结 4 1104
感动是毒
感动是毒 2021-01-21 15:09

I am trying to convert the following to use React.memo:

interface Props {
  // props...
}

export function Table({
          


        
相关标签:
4条回答
  • 2021-01-21 15:48

    Don't you need to pass a component as the first parameter of React.memo? I couldn't test it, but I feel like this is the thought process:

    // Overall format:
    export const Table = memo(MyComponent, MyFunction)
    
    // With empty arrow function:
    export const Table = memo(MyComponent, () => {})
    
    // With your code:
    export const Table = memo(MyComponent, ({propA, propB}: Props<TRowData>) => {
    
    })
    
    0 讨论(0)
  • 2021-01-21 15:50

    I solved it by keeping it as a function, renaming the function to TableComponent and doing:

    export const Table = memo(TableComponent) as typeof TableComponent
    
    0 讨论(0)
  • 2021-01-21 16:09

    Simple, just pass a non-arrow function to React.memo:

    export const Table = React.memo(function<T>(props: Props<T>) {
    
    })
    

    or if you need default export:

    export default React.memo(function Table<T>(props: Props<T>) {
    
    })
    
    0 讨论(0)
  • 2021-01-21 16:10

    With current React type declarations, it is not possible to create a generic component out of React.memo. A solution without type assertions is to add an additional memo function overload to leverage TS 3.4 higher order function type inference:

    import React, { memo } from "react"
    
    declare module "react" { // augment React types
      function memo<A, B>(Component: (props: A) => B): (props: A) => ReactElement | null
      // return type is same as ReturnType<ExoticComponent<any>>
    }
    

    You then will be able to make Table component generic. Just make sure to pass a generic function to memo:

    interface Props<T> {
      a: T
    }
    
    const TableWrapped = <T extends {}>(props: Props<T>) => <div>{props.a}</div>
    
    const Table = memo(TableWrapped)
    
    const App = () => (
      <>
        <Table a="foo" /> {/* (props: Props<string>) => ... */}
        <Table a={3} /> {/* (props: Props<number>) => ... */}
      </>
    )
    

    Playground

    0 讨论(0)
提交回复
热议问题