Home > Back-end >  Typescript React - map array as component
Typescript React - map array as component

Time:06-05

I have the following sub component I created and I want to use it as

<LangsLinks/>

inside main component in the same file. typescript throwing errors.

  const LangsLinks: (): JSX.Element[]  => {
    return appLinks.map((link) => {
      return (
        <Link key={link.text} href={link.relativeLink}>
          {link.text}
        </Link>
      )
    })
  }

error : 'LangsLinks' cannot be used as a JSX component.
  Its return type 'Element[]' is not a valid JSX element.
    Type 'Element[]' is missing the following properties from type 'ReactElement<any, any>': type, props, key

when I try to use Element[] I'm getting another error missing ReactElement<any, any> so I try to add it and so on. the app is work but I want to understand why is that happening. I dont want to use 'any'

the main component which I using the langLinks:

  return (
    <>
      <OneZeroSkipToMainContent
        text={'skipToMainContent'}
        dir={dir}
        className={'h-14 bg-gradient-to-r from-purple-500 to-pink-500'}
      />
      <header className=" z-50 justify-center   overflow-hidden  bg-gradient-to-br   ">
        <div className="flex mt-8  fixed z-50 right-2/4 p-4 translate-x-2/4  gap-x-2 mx-auto bg-light rounded-lg sm:w-150 lg:w-160 mobile:w-screen justify-between">
          <Logo />
          <ul className="flex flex-row gap-x-2   self-stretch">
            <div className="lg:flex flex-row gap-x-6  w-4/4  items-center hidden  md:visible  ">
              <LangsLinks />
            </div>
          </ul>
          <ul className="flex flex-row gap-x-2 items-center  mx-r-auto  w-1/3 justify-end mobile:hidden  sm:block md:flex">
            {langs.map((lang, i) => {
              return (
                <li key={lang}>
                  <ChangeLangButton
                    src={`/icons/flags/${i   1}.png`}
                    lang={lang}
                  ></ChangeLangButton>
                </li>
              )
            })}
          </ul>
          <div className="sm:block md:hidden pl-10 cursor-pointer  relative  ">
            <Image src="/header/mobile-menu.svg" alt="menu" layout="fill" />
          </div>
        </div>
      </header>
    </>
  )
}

CodePudding user response:

you cannot return multiple root nodes from a component. you will need to wrap it with <> or React.Fragment;

example:

  const LangsLinks: (): JSX.Element[]  => {
    return <> 
      {appLinks.map((link) => {
        return (
          <Link key={link.text} href={link.relativeLink}>
            {link.text}
          </Link>
        )
      })}
    </>
  }

CodePudding user response:

You can try below as a type.

NodeListOf<Element>

CodePudding user response:

I do not understand why are you trying to set a type to your component return. Just build it like a normal functional component, I'll rewrite it a bit:

const LangsLinks = () => {
    return (
       <>
          {appLinks.map((link) => (
              <Link key={link.text} href={link.relativeLink}>
                {link.text}
              </Link>
            )
          )}
       </>
      )
  }

Just keep it simple, it does not work for you this way?

EDIT: Even more simple:

const LangsLinks = () => (
           <>
              {appLinks.map((link) => (
                  <Link key={link.text} href={link.relativeLink}>
                    {link.text}
                  </Link>
                )
              )}
           </>
          )

  • Related