【问题标题】:Typescript + React, rendering an array from a stateless functional componentTypescript + React,从无状态功能组件渲染数组
【发布时间】:2018-03-24 09:37:30
【问题描述】:

React 团队 announced 从 React 16 开始:

您现在可以从组件的渲染方法返回一个元素数组。

这适用于常规类组件的打字稿,但我无法让它适用于无状态功能组件。

如果您想自己复制,请参阅this repo

代码:

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

构建这个sniper会导致以下错误:

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

如您所见,从常规类组件渲染数组是可行的,但在从无状态功能组件渲染数组时会失败。

我不确定问题出在我的代码/设置、DefinitelyTyped 反应类型还是打字稿本身。

【问题讨论】:

    标签: reactjs typescript definitelytyped


    【解决方案1】:

    “您现在可以从组件的 render 方法返回一个元素数组。”

    JSX 数组正在被 React.Components render 方法编译。无状态功能组件缺少该渲染方法。

    您可以将元素数组包装在父 div 而不是数组中,也可以使用常规类组件。

    【讨论】:

    【解决方案2】:

    您可以通过将组件转换为 any 来抑制错误并使代码正常工作:

    const Bar: any = () => [<div>bar</div>, <div>baz</div>]
    

    【讨论】:

    • 是的,我知道如何压制或解决这个问题;)。我提出了这个问题,希望要么暴露 TS/React 错误,要么了解我做错了什么。
    • 似乎两者都不是,而是DefinitelyTyped 中的一个未解决问题。见github.com/DefinitelyTyped/DefinitelyTyped/issues/…
    • 这正是我想要的,我的 Google 技能让我失望了!谢谢,丹麦人
    【解决方案3】:

    在解决开放的Definitely Typed 问题之前,最好的解决方法可能是改用&lt;React.Fragment/&gt;。出于功能目的,我不认为有任何区别:

    const Bar: React.SFC<CheckoutProps> = (props) => {
      return (
        <React.Fragment>
          <div>bar</div>
          <div>baz</div>
        </React.Fragment>
      );
    };
    

    【讨论】:

    • 注意 SFCStatelessComponent 在 React 17 中已弃用。弃用通知建议用户改用 FunctionComponentFC