【React】使用Swiper报错`Swiper` needs at least one child
问题
聊天页面的表情面板,滑动效果使用了ant design mobile的Swiper。
原代码中,Swiper 组件在 isShow 为 false 时渲染的是 <></>(空元素),控制台警告Swiper
needs at least one child,Swiper.Item 需要一个默认的内容,不能直接为空。
<Swiper>
{isShow ? emojiPages.map((page, pageIndex) => (
<Swiper.Item key={pageIndex}>
<Grid columns={7} gap={8}>
{page.map((item, index) => (
<Grid.Item
key={index}
onClick={() => setContent(content + item.text)}
>
<div style={{textAlign: 'center'}}>{item.text}</div>
</Grid.Item>
))}
</Grid>
</Swiper.Item>
)) : <></>}
</Swiper>
问题分析
通过判断 emojiPages.length > 0 来确保只有在有表情数据时才渲染 Swiper.Item,避免 Swiper 组件没有子元素的警告。
这个警告是因为 Swiper
组件在 isShow === false
时仍然在渲染,但没有子元素,而 antd-mobile
需要至少一个 Swiper.Item
作为子元素,否则会报错。
解决方案
方法1. 提供一个空 Swiper.Item
作为占位
在 isShow === false
时,仍然渲染 Swiper.Item
,但让它保持空白:
<Swiper style={{ display: isShow ? 'block' : 'none' }}>
{emojiPages.length > 0 ? (
emojiPages.map((page, pageIndex) => (
<Swiper.Item key={pageIndex}>
<Grid columns={7} gap={8}>
{page.map((item, index) => (
<Grid.Item
key={index}
onClick={() => setContent(prev => prev + item.text)}
>
<div style={{ textAlign: 'center' }}>{item.text}</div>
</Grid.Item>
))}
</Grid>
</Swiper.Item>
))
) : (
// ⚠️ 这里添加一个空的 `Swiper.Item` 避免警告
<Swiper.Item key="placeholder">
<div style={{ height: 0, visibility: 'hidden' }}></div>
</Swiper.Item>
)}
</Swiper>
方法2. 完全不渲染 Swiper
如果不想让 Swiper
组件在 isShow === false
时渲染,可以用 条件渲染:
{isShow && emojiPages.length > 0 && (
<Swiper>
{emojiPages.map((page, pageIndex) => (
<Swiper.Item key={pageIndex}>
<Grid columns={7} gap={8}>
{page.map((item, index) => (
<Grid.Item
key={index}
onClick={() => setContent(prev => prev + item.text)}
>
<div style={{ textAlign: 'center' }}>{item.text}</div>
</Grid.Item>
))}
</Grid>
</Swiper.Item>
))}
</Swiper>
)}
- 方法 1:提供一个占位的
Swiper.Item
,让Swiper
始终存在,但不会报错。 - 方法 2:在
isShow === false
时,完全不渲染Swiper
,但可能会导致Swiper
重新初始化。
思考
方法 1(推荐):提供一个占位的 Swiper.Item
-
优点:
- 性能优化:
Swiper
组件始终存在,不会被频繁销毁和重新初始化,避免了组件状态的重置和性能损耗。 - 用户体验:切换表情面板时不会发生过渡或初始化的闪烁,保持了流畅的交互体验。
- 避免报错:通过占位的
Swiper.Item
,确保Swiper
始终有子元素,避免了警告或错误。
- 性能优化:
-
缺点:
- 会占用一些不必要的空间,即使表情面板不显示。
方法 2:在 isShow === false
时,完全不渲染 Swiper
-
优点:
- 避免占用空间:当不显示表情面板时,完全不渲染
Swiper
,节省了页面的布局空间。 - 简洁:如果你希望
Swiper
只在需要时出现,这种方式比较直接。
- 避免占用空间:当不显示表情面板时,完全不渲染
-
缺点:
- 性能问题:如果切换
isShow
状态频繁,会导致Swiper
组件重新初始化,这可能会影响性能,尤其是在复杂的表情面板或较大页面的情况下。 - 重新渲染问题:有时候切换过程中可能会导致
Swiper
状态不一致或初始化问题。
- 性能问题:如果切换
总结:
- 如果你的表情面板是一个经常切换的功能(比如用户频繁开关表情面板),建议使用 方法 1。这样避免了
Swiper
的频繁销毁和初始化,能保证更流畅的用户体验。 - 如果你对性能要求较高,并且表情面板的切换并不频繁,或者你希望完全控制其占用空间,可以选择 方法 2。
个人推荐方法 1,因为它能保持组件的稳定性和流畅的交互体验,特别是在切换时不需要重新加载内容。
原文地址:https://blog.csdn.net/YvetW/article/details/146450461
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.kler.cn/a/597766.html 如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.kler.cn/a/597766.html 如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!