Typescript + React, rendering an array from a stateless functional component
Asked Answered
C

3

11

The React team announced that since React 16:

You can now return an array of elements from a component’s render method.

This works in typescript for regular class components, but I cannot get it to work for stateless functional components.

See this repo if you want to reproduce for yourself.

Code:

import * as React from 'react';

// See this example working in a non-TS environment: https://codesandbox.io/s/ppl3wopo8j
class Hello extends React.Component {
    render() {
        return <div>
        <Foo />
        <Bar /> {/* Error: 'JSX element type 'Element[]' is not a constructor function for JSX elements. */}
      </div>;
    }
}

class Foo extends React.Component {
    render() {
        return [<div>foo</div>, <div>fooz</div>];
    }
}

function Bar() {
    // Cannot render an array from a SFC
    return [<div>bar</div>, <div>baz</div>];
}

Building this snipper results in the following error:

'JSX element type 'Element[]' is not a constructor function for JSX elements.
  Property 'render' is missing in type 'Element[]'.'

As you can see, rendering an array from a regular class component works, but it fails when rendering an array from a stateless functional component.

I'm unsure whether the problem lies with my code/setup, the DefinitelyTyped react types, or with typescript itself.

Cronus answered 12/10, 2017 at 12:36 Comment(0)
W
4

Until the open Definitely Typed issue has been resolved, the best work around is probably just to use <React.Fragment/> instead. For functional purposes, I don't think there is any difference:

const Bar: React.SFC<CheckoutProps> = (props) => {
  return (
    <React.Fragment>
      <div>bar</div>
      <div>baz</div>
    </React.Fragment>
  );
};
Whizbang answered 11/12, 2018 at 7:3 Comment(1)
Note SFC and StatelessComponent are deprecated in React 17. The deprecation notice suggests users use FunctionComponent or FC instead.Martimartial
M
-3

"You can now return an array of elements from a component’s render method."

The array of JSX is being compiled by React.Components render method. A stateless functional component lacks that render method.

You could either wrap your array of elements in a parent div instead of the array or use a regular class component.

Maurili answered 12/10, 2017 at 16:28 Comment(2)
No. You can return arrays even from stateless functional components. See example: codepen.io/pawelgrzybek/pen/WZEKWjPhilipson
Thanks for the note. Looks like it was a type error.Maurili
P
-4

You can suppress the error and have your code working by casting your component as any:

const Bar: any = () => [<div>bar</div>, <div>baz</div>]
Philipson answered 13/10, 2017 at 8:29 Comment(3)
Yeah, I know how to suppress or work around the issue ;). I raised this question hoping to either surface a TS/React bug, or learn about how I'm doing something wrong.Cronus
It seems it's neither, but an open issue in DefinitelyTyped. See github.com/DefinitelyTyped/DefinitelyTyped/issues/…Philipson
That's exactly what I was looking for, my Google skills have failed me! Thanks, DaneCronus

© 2022 - 2024 — McMap. All rights reserved.