javascript 如何在React.memo中使用Props和泛型

axkjgtzd  于 2023-04-19  发布在  Java
关注(0)|答案(4)|浏览(145)

我正在尝试将以下内容转换为使用React.memo

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

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

}

像这样(不正确):

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


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

})

如何纠正此语法?目前它有以下错误:

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

oxf4rvwz1#

我通过将memo和non-memo分开并进行一些类型转换来解决它:

const TableComponent = <T,>(props: TableComponentProps<T>) => {
 // ...
}

// or
function TableComponent<T>(props: TableComponentProps<T>) {
  // ...
}

然后:

export const Table = memo(TableComponent) as typeof TableComponent

或者:

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

sgtfey8w2#

使用当前的React类型声明,不可能从React.memo中创建通用组件。没有类型Assert的解决方案是添加额外的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) => B
  // return type is same as ReturnType<ExoticComponent<any>>
}

然后你就可以使Table组件成为泛型了。只要确保传递一个泛型函数给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

de90aj5v

de90aj5v3#

你不需要传递一个组件作为React.memo的第一个参数吗?我无法测试它,但我觉得这是思考过程:

// 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>) => {

})
nfzehxib

nfzehxib4#

很简单,只需将一个非箭头函数传递给React.memo

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

})

或者如果需要默认导出:

export default React.memo(function Table<T>(props: Props<T>) {

})

编辑:你可以用下面的代码来检查这是否有效:

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});

element的类型为

React.FunctionComponentElement<{someField: number}>

相关问题