简体   繁体   English

如何在 React.memo 中使用带有泛型的 Props

[英]How to use Props with Generics with React.memo

I am trying to convert the following to use React.memo :我正在尝试将以下内容转换为使用React.memo

interface Props<TRowData> {
  // props...
}

export function Table<TRowData>({
  propA,
  propB
}: Props<TRowData>) {

}

Like so (incorrect):像这样(不正确):

interface Props<TRowData> {
  // props...
}



export const Table = memo<Props<TRowData>>(
({
  propA,
  propB
}) => {

})

How can I correct this syntax?如何更正此语法? Currently it has this error:目前它有这个错误:

// Cannot find name 'TRowData'.
export const Table = memo<Props<TRowData>>(
                                ~~~~~~~~

With current React type declarations, it is not possible to create a generic component out of React.memo .使用当前的 React 类型声明,不可能从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 :没有类型断言的解决方案是添加额外的memo函数重载以利用 TS 3.4 高阶函数类型推断

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.然后,您将能够使Table组件通用。 Just make sure to pass a generic function to memo :只需确保将通用函数传递给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 操场

I solved it by keeping it as a function, renaming the function to TableComponent and doing:我通过将其保留为函数来解决它,将函数重命名为TableComponent并执行以下操作:

export const Table = memo(TableComponent) as typeof TableComponent

Edit, this one also works:编辑,这个也有效:

const typedMemo: <T>(c: T) => T = React.memo
export const Table = typedMemo(TableComponent)

Don't you need to pass a component as the first parameter of React.memo ?你不需要传递一个组件作为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>) => {

})

Simple, just pass a non-arrow function to React.memo :简单,只需将一个非箭头函数传递给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>) {

})

Edit: You can check that this works with the following code:编辑:您可以检查这是否适用于以下代码:

type MyProps<T> = {someField: T};
const MyComponent = React.memo(function <T>({someField}: MyProps<T>) {
  return <div>{someField}</div>
});

<MyComponent someField={222} />;
<MyComponent someField={'MYSTRING'} />;

const element = React.createElement(MyComponent, {someField: 22});

Type of element is element类型是

React.FunctionComponentElement<{someField: number}>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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