在React + TypeScript下面是否有一种干净的方法来编写这种语法?当我这样做时,出现以下错误。
JSX element type 'Container' does not have any construct or call signatures.
代码:
const Container = this.props.useFoo ? <Foo {...fooProps}></Foo> : <div></div>;
return (
<Container>
<div {...someAttrs}>
{this.props.children}
</div>
</Container>
);
我知道我可以使用字符串Tag = "div"
动态定义容器标签,并使用<Tag>...</Tag>
,但这似乎不适用于组件。我这样做的唯一方法是将子级内容保存到变量中,然后执行以下操作,使它变得冗长且丑陋。
const content = <div {...someAttrs}>{this.props.children}</div>;
return (
<>
{this.props.useFoo ? <Foo {...fooProps}>{content}</Foo> : <div>{content}</div>}
</>
);
编辑:
我决定采用以下语法:
const container = (content) => {
return this.props.useFoo ? <Foo {...fooProps}>{content}</Foo> : <div>{content}</div>;
};
return container(
<div {...someAttrs}>
{this.props.children}
</div>
);
答案 0 :(得分:2)
⚠请注意,我刚开始使用“ TypeScript”(使用React)。
似乎您正在将渲染的Component实例分配给Container
,而不是指定容器的形状(类)应该是什么。
因此,您需要传递类或内部字符串"div"
并将容器设置为React.ReactType
(可以是类,功能组件或内部组件,例如div
,{ {1}},p
等)。
span
您可以在Sandbox上查看演示。
如果沙盒链接无法正常工作,请提供完整的源代码。
function Demo(props: DemoProps) {
const Container: React.ReactType = props.useFoo ? Foo : "div";
return (
<Container>
<div>{props.children}</div>
</Container>
);
}
☝您可以看到使用import * as React from "react";
import { render } from "react-dom";
import "./styles.css";
interface DemoProps {
useFoo?: boolean;
children: string | JSX.Element | JSX.Element[];
}
const Foo = () => <div>Foo</div>;
function Demo(props: DemoProps) {
const Container: React.ReactType = props.useFoo ? Foo : "div";
return (
<Container>
<div>{props.children}</div>
</Container>
);
}
function App() {
return (
<div>
<Demo useFoo>This is a demo App</Demo>
<Demo>This is a demo App</Demo>
</div>
);
}
const rootElement = document.getElementById("root");
render(<App />, rootElement);
时容器重写了子级内容。
答案 1 :(得分:0)
第一个示例的问题是,要传递已渲染的组件,而不是对其的引用(稍后将进行渲染),则解决该问题的方法是:
// imports ...
function Foo(props) {
console.log('using foo')
return <main>{props.children}</main>
}
function Baz(props) {
console.log('using baz')
return <div>{props.children}</div>
}
function ConditionalComponent(props) {
const Container = props.useFoo ? Foo : Baz;
return (
<Container>
{props.children}
</Container>
)
}