javascript - 如何在 TypeScript React 组件中返回字符串或 JSX 元素?
问题描述
我收到了这个奇怪的 TypeScript 错误:
import React from 'react'
type Props = {
children: string
}
const Container = (props: Props) => {
const isNew = true // make an api call...
if (isNew) {
return <NewContainer {...props} />
} else {
return <OldContainer {...props} />
}
}
const NewContainer = ({ children }: Props) => {
const isSpecial = useIsSpecial()
if (!children) {
return null
}
if (!isSpecial) {
return children
}
return <a>{children}</a>
}
const OldContainer = ({ children }: Props) => {
const isSpecial = useIsSpecial()
if (!children) {
return null
}
if (!isSpecial) {
return children
}
return <a>{children}</a>
}
那些被这样使用:
<Container>foo</Children>
然后我得到这些打字稿错误:
'NewContainer' cannot be used as a JSX component.
Its return type 'string | Element' is not a valid JSX element.
Type 'string' is not assignable to type 'Element'.
'OldContainer' cannot be used as a JSX component.
Its return type 'string | Element' is not a valid JSX element.
Type 'string' is not assignable to type 'Element'.
如果我删除if (!isSpecial) return children
,并将其更改为if (!isSpecial) return <span>{children}</span>
,它工作正常。为什么它不允许我返回一个字符串?如何在 TypeScript 中解决这个问题?
解决方案
TypeScript 的 React 类型不正确,不允许string
作为组件类型的返回值。
一个 React 组件可以返回以下类型(一个 React 节点):
- 无效的
- 布尔值
- 数字
- 细绳
- 反应元素
- 反应门户
- 数组(反应节点或未定义)
您可以轻松地运行下面的代码片段来测试它并观察组件是否正确呈现。
function HelloWorld() { return "Hello, World!"; }
ReactDOM.render(React.createElement(HelloWorld), document.getElementById("root"));
<script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<div id="root"></div>
您还可以注意到运行也可以ReactDOM.render("Hello, World!", ...)
,因为render
React DOM 的功能需要一个有效的 React 节点,并且string
就是这样。
但是您也可以使用包的isNode
功能prop-types
或Flow 的React$Node
类型定义作为参考,以验证 React Node 类型接受什么,这两种类型定义都是由Facebook Meta 本身创建的。
TypeScript 维护人员似乎对修复此问题以及ReactNode
错误接受的不正确类型不感兴趣undefined
,因此您只能求助于解决方法,例如将文本包装到 Fragment 中,如其他评论中所述。
推荐阅读
- pandas - 堆叠、拆垛、融化、旋转、转置?将多列转换为行(PySpark 或 Pandas)的简单方法是什么?)
- mysql - 将 Django 查询集转换为列表时,表情符号的 mySQL unicode 解码错误
- javascript - 以下语法在带有反应钩子的 JavaScript 中是什么意思
- reactjs - 调用 firebase 函数的问题
- python - AttributeError:“列表”对象没有属性“时间”
- javascript - 如何编写可以生成用户指定数量的 css 方块的脚本
- reactjs - 为什么我的地图功能会破坏 React 中的 Swiperjs 组件?
- c++ - 如何创建可销毁的线程安全单例 C++?
- apache-spark - 将“t”和“f”作为布尔值输入到 Cassandra
- docker - Docker 多栈部署和多 nginx-proxy 部署