更新对17的React 17-打字条 - 反应节点类型的儿童不再处理内联条件渲染`void'
使用React.ReactNode
儿童
的类型时,如果有任何内联条件渲染,它将失败。我目前正在使用swr
获取数据,因此我会收到这样的错误:
键入'false | void |元素|未定义的“不能分配为'reactnode'。 键入“ void”不可分配给'reactnode'
我不确定是否以前React.ReactNode
允许void
,或者是否由于以前的隐式孩子而默默错过了。也许这是我应该对React或SWR开放的问题?
以前
我的React 17页组件看起来像这样。关于隐式儿童的破裂变化有很多信息,但我总是明确说明我的。也许是类型的孩子:void
,undefined
或null
将被视为隐式的孩子吗?
type PageProps = {
children: React.ReactNode
}
const Page = ({ children }: PageProps) = > {
return (
<div>
<Header />
<div>
{children}
</div>
<Footer />
</div>
)
}
export default Page
问题
第一个问题“提供了多个孩子”
这个JSX标签的“儿童'Prop都期望一个单身孩子 “反应节点”,但提供了多个孩子。TS(2746)
修复
此类型允许多个或单身子女的这种类型的修复。我确实希望我们能在不明确或很多的情况下摆脱困境,但确实可以提供更强大的打字。
type PageProps = {
children: React.ReactNode[] | React.ReactNode;
};
使用SWR失败的示例页面
const UsersPage: NextPage = () => {
const { data, error } = useSWR('/api/user', fetcher)
return (
<Page>
{users && (
<pre>
{JSON.stringify(users, null, 2)}
</pre>
)}
</Page>
)
}
将为我带来以下错误:
键入'false | void |元素|未定义的“不能分配为'reactnode'。 键入“ void”不可分配给键入'reactnode'
When using the React.ReactNode
type for children
if there are any inline conditional renders it will fail. I am currently using SWR
to fetch data so I get an error like this:
Type 'false | void | Element | undefined' is not assignable to type 'ReactNode'. Type 'void' is not assignable to type 'ReactNode'
I'm not sure if previously React.ReactNode
allowed void
or if it was just silently missed due to implicit children before. Maybe this is an issue I should open up with React or SWR?
Previously
My React 17 Page component looked something like this previously. There is a lot of information around the breaking changes of implicit children but I always explicitly stated mine. Maybe a child of type: void
, undefined
, or null
would be considered an implicit child though?
type PageProps = {
children: React.ReactNode
}
const Page = ({ children }: PageProps) = > {
return (
<div>
<Header />
<div>
{children}
</div>
<Footer />
</div>
)
}
export default Page
Problems
First Issue "multiple children were provided"
This JSX tag's 'children' prop expects a single child of type 'ReactNode', but multiple children were provided.ts(2746)
Fix
That's fixed simply enough with this type that allows multiple or single children. I do wish we could get away without being explicit about or many, but it does give stronger typing.
type PageProps = {
children: React.ReactNode[] | React.ReactNode;
};
Example Page Failing using SWR
const UsersPage: NextPage = () => {
const { data, error } = useSWR('/api/user', fetcher)
return (
<Page>
{users && (
<pre>
{JSON.stringify(users, null, 2)}
</pre>
)}
</Page>
)
}
This will give me the following error:
Type 'false | void | Element | undefined' is not assignable to type 'ReactNode'. Type 'void' is not assignable to type 'ReactNode'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
选项1:将
void
添加到react> react node
键入一种方法是在类型上允许
void
这样:发生错误,
您最终会出现给定上述实现
page
组件的混乱错误:这令人困惑,因为它抱怨单身与多个孩子,但是,如果您从新键入中删除空白会很好,所以这似乎不是关于它是否是数组。
可以通过包装
{children}
呈现这样的效果来解决这:&lt;&gt; {children}&lt;/&gt;
示例
>示例>示例选项2:处理
void
另一个选项将是确保如果有条件的内联渲染返回
void
默认为空的react fragment(&lt;&gt;&gt;&lt;/&gt; )喜欢这样:
结尾笔记
,尽管选项2 可能被认为更“适当”,而不是覆盖和处理
react> react node
类型,但这将开始变得多余,感觉就像那时的反pates。 选项2 还需要您使用有条件渲染的任何地方更新。 选项1 修补它,以便您可以继续使用void
返回。 不确定这是否有缺点。
我 代码> void 然后您将遇到此问题,如果fetcher不返回
void
,则可以完全避免此问题,因为使用
将返回回调值或未定义的
reactnode
可以处理[undefined
,false
,null
]。如果
组件。您只需将其保留为:使用wrr
不返回void,您甚至不需要更改儿童
属性儿童:React.ReaeActNode
,因为React node
Incordreactfragment
是一个迭代的react> react> react> reactnode
哪个包括单身或多个孩子。React类型定义的React Node类型
Option 1: Add
void
to theReactNode
typeOne way would be to allow
void
on the type like so:An Error Occurs
You will end up this confusing error given the above implementation of the
Page
component:This is confusing because it's complaining about single vs multiple children, yet if you remove void from the new typing it will be fine, so this seems to not be about whether it's an array or not.
This can be resolved by wrapping the
{children}
render like so:<>{children}</>
Example
Option 2: Handle the
void
Another option would be to handle the void by making sure that if the conditional inline render returns
void
default to an empty React fragment (<></>
) like so:Closing Notes
Although Option 2 may be considered more "proper" rather than overriding and handling the
ReactNode
type, this would start to get redundant and feels like an anti-pattern at that point. Option 2 would also require you to update anywhere with a conditional render which gets cumbersome. Option 1 patches it so that you can continue utilizingvoid
returns. I'm not certain if there is a downside to this⭐️ A Further Dig ⭐️ -- The Real Answer ????
useSwr
returns the types of thefetcher
, if the fetcher returnsvoid
then you will run into this problem, if the fetcher does not returnvoid
then this problem can be avoided completely asuseSWR
will return the callback value orundefined
whichReactNode
can handle [undefined
,false
,null
].You will not even need to change the
children
property on thePage
component ifuseSwr
does not return void. You can simply keep it as:children: React.ReactNode
sinceReactNode
includesReactFragment
which is an iterableReactNode
which includes single or multiple children.ReactNode Type from React Type Definition