当前位置: 首页 > news >正文

【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,因为它能保持组件的稳定性和流畅的交互体验,特别是在切换时不需要重新加载内容。

相关文章:

  • 前端会话控制技术:cookie/session/token
  • 特斯拉Optimus 2.0:多模态感知与强化学习引领家庭场景变革
  • 【递归、搜索和回溯算法】专题三 :穷举VS暴搜VS深搜VS回溯VS剪枝
  • WebGL图形编程实战【2】:动态着色 × 纹理贴图技术揭秘
  • 学习Flutter:搭建第一个 Flutter 应用
  • StarRocks 主键(Primary Key)深度解析
  • MATLAB+Arduino控制小车直行+转向
  • 竞赛团队招募系统----山东大学web课程设计
  • cool-admin-midway 使用腾讯云cos上传图片
  • SAP SD学习笔记35 - ATP(可用性检查)的各种Pattern
  • NLP高频面试题(十二)——Lora微调的原理、什么是Qlora
  • AWS NoSQL解决方案全景图
  • 【MySQL笔记】数据类型
  • 外设的中断控制
  • java设计模式之代理模式《赛博园丁的代理觉醒》
  • Mybatis注解的基础操作——02
  • 基于STM32单片机的智能手环/音乐播放/语音识别
  • RWKV-7:超越Transformer的新一代RNN架构解析
  • Vue3组件设计模式:高可复用性组件开发实战
  • 【数据结构】_单链表_相关面试题(一)
  • GDP逼近五千亿,向海图强,对接京津,沧州剑指沿海经济强市
  • “水运江苏”“航运浙江”,江浙两省为何都在发力内河航运?
  • 哲学新书联合书单|远离苏格拉底
  • 图讯丨习近平出席中国-拉美和加勒比国家共同体论坛第四届部长级会议开幕式
  • 牛市早报|中美日内瓦经贸会谈联合声明公布
  • 特朗普开启第二任期首次外访:中东行主打做生意,不去以色列