React + TypeScript 语法:动态更改容器组件

Coo*_*ter 4 typescript reactjs

在 React+TypeScript 中是否有一种干净的方法来编写下面这种语法?当我这样做时,我收到以下错误。

JSX element type 'Container' does not have any construct or call signatures.
Run Code Online (Sandbox Code Playgroud)

代码:

const Container = this.props.useFoo ? <Foo {...fooProps}></Foo> : <div></div>;

return (
        <Container>
            <div {...someAttrs}>
                {this.props.children}
            </div>
        </Container>
);
Run Code Online (Sandbox Code Playgroud)

我知道我可以使用字符串动态定义容器标签,即Tag = "div",并使用<Tag>...</Tag>,但这似乎不适用于组件。我能做到这一点的唯一方法是将子内容保存到变量中,然后执行以下操作,我发现它冗长且丑陋。

const content = <div {...someAttrs}>{this.props.children}</div>;

return (
    <>
        {this.props.useFoo ? <Foo {...fooProps}>{content}</Foo> : <div>{content}</div>}
    </>
);
Run Code Online (Sandbox Code Playgroud)

编辑:

我决定使用以下语法:

const container = (content) => {
    return this.props.useFoo ? <Foo {...fooProps}>{content}</Foo> : <div>{content}</div>;
};

return container(
    <div {...someAttrs}>
        {this.props.children}
    </div>
);
Run Code Online (Sandbox Code Playgroud)

dan*_*die 5

\n\n

\xe2\x9a\xa0请注意,我刚刚开始使用“TypeScript”(使用 React)。

\n\n

看起来您正在将渲染的 Component 实例分配给Container不是指定容器的形状(类)应该是什么。

\n\n

因此,您需要传递类或内部字符串,"div"并将容器设置为React.ReactType(可以是类、功能组件或内部组件,例如div, p,span等)。

\n\n
function Demo(props: DemoProps) {\n  const Container: React.ReactType = props.useFoo ? Foo : "div";\n\n  return (\n    <Container>\n      <div>{props.children}</div>\n    </Container>\n  );\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

您可以在 Sandbox 上查看演示。

\n\n

编辑so.answer.54448317

\n\n
\n\n

完整源代码,以防沙盒链接无法工作。

\n\n

代码

\n\n
import * as React from "react";\nimport { render } from "react-dom";\n\nimport "./styles.css";\n\ninterface DemoProps {\n  useFoo?: boolean;\n  children: string | JSX.Element | JSX.Element[];\n}\n\nconst Foo = () => <div>Foo</div>;\n\nfunction Demo(props: DemoProps) {\n  const Container: React.ReactType = props.useFoo ? Foo : "div";\n\n  return (\n    <Container>\n      <div>{props.children}</div>\n    </Container>\n  );\n}\n\nfunction App() {\n  return (\n    <div>\n      <Demo useFoo>This is a demo App</Demo>\n      <Demo>This is a demo App</Demo>\n    </div>\n  );\n}\n\nconst rootElement = document.getElementById("root");\nrender(<App />, rootElement);\n
Run Code Online (Sandbox Code Playgroud)\n\n

结果

\n\n

演示结果

\n\n

\xe2\x98\x9d 可以看到当useFoo使用时,容器覆盖了子级内容。

\n