TransWikia.com

wrap children for react component which has children restricted to certain types

Stack Overflow Asked by Danielo515 on January 15, 2021

I have a component that I restricted to have certain types of children using flow types. However, now I have several situations where it is convenient to wrap those components in other component that just returns one of the valid components but with some defaults attached. Even grouping some of those valid components using react fragments gives me weird errors that I am unable to debug.

Here is a piece of sample code (that you can run on flow playground):

//@flow
import React from 'react'
import type { Node, Element, ChildrenArray } from 'react'

type ItemType = Element<typeof ListItem | typeof ListHeader>

type Props = {
  children: ChildrenArray<ItemType>,
}

function List({ children }: Props) {
  return <div>{children}</div>
}

type ItemProps = {
  children: Node,
  onClick?: () => void,
}

function ListItem({ children, onClick }: ItemProps) {
  return <div onClick={onClick}>{children}</div>
}

type HeaderProps = {
  children: Node,
}

function ListHeader({ children }: HeaderProps) {
  return <div>{children}</div>
}

const Row = ({ left, right }: { left: string, right: Node }): Node => {
  return (
    <ListItem>
      {left}
      <span>{right}</span>
    </ListItem>
  )
}

const x = () => (
  <List>
    <Row left="gender" right="${gender}" />
    <Row left="birthDate" right="xxx" />
    <Row left="Number" right="xxx" />
    <Row left="sendEnrollmentLetter" right="stuff" />
  </List>
)

What is the correct way of following such pattern?

On flow playground you will not see errors because, if you open the console you will see that it just blows up.

This is the concrete error I’m getting on my project:

Cannot create `List` element because in array element of property `children`: 
Either property `children` is missing in  object type [1] but exists in  `HeaderProps` [2] in property `props`. 
Or property `children` is missing in  object type [1] but exists in  `ItemProps` [3] in property `props`.

One Answer

Running your code snippet on a project gave the following errors for the child components inside x

Cannot create `Parent` element because Could not decide which case to select, since case 1 [1] may work but if it doesn't case 2 [2] looks promising too. To fix add a type annotation to return [3].Flow(incompatible-type)

Assuming these are the errors you're getting, flow can't infer what the type of your components should be, so it wants you to manually annotate them. Adding return type of Node should do it

const Wrapper = (): Node => (
  <>
    <Foo disabled />
    <Bar />
  </>
);

const Defaults = (): Node => <Foo disabled={false} />;

const x = (
  <Parent>
    <Wrapper />
    <Wrapper />
    <Defaults />
  </Parent>
);

Though as a side note I'd strongly recommend you move to using import * as React from 'react'; so you can use React.Node instead. Otherwise Node from react will conflict with usage of html Node in the future.

Answered by Brianzchen on January 15, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP