Definitelytyped: [@types/react] React.memo does not accept children

Created on 5 Mar 2020  路  6Comments  路  Source: DefinitelyTyped/DefinitelyTyped

It seems that React.memo() results in a component that won't accept JSX children:

This works, note that {children} raises no error as expected because PropsWithChildren is used in the resolved inner component parameter:

const Foo = React.memo<{ title: string }>(({ children, title }) => (
    <div title={title}>{children}</div>
));

Rendering the resulting component with no children works:

const test = <Foo title="foo" />;

Rendering with JSX children results in Error: Property 'children' does not exist on type 'IntrinsicAttributes & { title: string; }'

const test2 = (
    <Foo title="foo">
       <b>Hello</b>
    </Foo>
);

I wonder if ExoticComponent should use (props: PropsWithChildren<P>) instead of just (props: P) as it does now? It seems to fix the issue local. Is there some reason not to do that?

  • [x] I tried using the @types/react package and had problems.
  • [x] I tried using the latest stable version of tsc. https://www.npmjs.com/package/typescript
  • [x] I have a question that is inappropriate for StackOverflow. Asked on gitter.
  • [x] [Mention](https://github.com/blog/821-mention-somebody-they-re-notified) the authors (see Definitions by: in index.d.ts) so they can respond.

    • Authors: @johnnyreilly @bbenezech @pzavolinsky @digiguru @ericanderson @tkrotoff @DovydasNavickas @onigoetz @theruther4d @guilhermehubner @ferdaber @jrakotoharisoa @pascaloliv @hotell @franklixuefei @Jessidhia @pshrmn @threepointone @saranshkataria

Most helpful comment

I kinda agree with @aaronbeall . IMHO this should be handled by some linter, not type-system -> that you're using non memoized children within memoized component.

All 6 comments

Please note that if you鈥檙e passing children to a .memo component, it鈥檒l fail the props check every time, making the memoisation useless. (Since children will be a new object every time). So maybe this shouldn鈥檛 be changed?

@threepointone Unless the children are themself memo'd (and haven't re-rendered), right?

Maybe, but it seems like extra work if it鈥檚 going to be static in that fashion. Simpler then to memoise a component that already includes the children in it (which could still change for different props)

@threepointone True, but JSX composition is a nice feature. The same argument could be made against PureComponent allowing children.

You鈥檙e right, PureComponent probably shouldn鈥檛 accept children either 馃槄

I don鈥檛 feel strongly about this type change, just pointing out it might not be as helpful as you鈥檇 think. I do recommend you consider restructuring your code instead.

I kinda agree with @aaronbeall . IMHO this should be handled by some linter, not type-system -> that you're using non memoized children within memoized component.

Was this page helpful?
0 / 5 - 0 ratings