• 【React 】折叠面板,点击展开时再请求数据


    需求背景:使用折叠面板的形式展示数据,面板内部数据需要在打开时请求接口获取。

    遇到问题:最开始使用Antd 的折叠面板组件,它对于数据直接渲染是没问题的,但是不好满足打开面板时再动态加载数据的需求,于是自己手写了一个。

    效果展示(已脱敏):
    在这里插入图片描述

    话不多说,以下是手写的组件代码:

    面板的header 内容结构可以根据自己需要调整

    /* eslint-disable @typescript-eslint/no-unused-vars */
    import { DownOutlined, RightOutlined } from '@ant-design/icons';
    import { Col, Row } from 'antd';
    import { useRef, useState } from 'react';
    import './style.less';
    // 内容
    import TableList from './TableList';
    
    /** ===================================
     * @names: 自定义折叠面板业务组件
     * @description:
     * @author:
     * @date: 2024-06-20
     *======================================*/
    
    export default function CollapseList(props: any) {
      const [active, setActive] = useState(false);
      const tableRef = useRef<any>();
      return (
        <div className="collapse-item">
          <div className="collapse-item-header">
            <Row>
              <Col span={12}>
                <div>test</div>
              </Col>
              <Col span={8}>
                <div>2022-06-20</div>
              </Col>
              <div className="expand">
                {!active ? (
                  <div
                    className="expandIconCpe"
                    onClick={() => {
                      setActive(!active);
                      // 点击展开时调用子组件加载数据的方法请求
                      tableRef.current?.handleGetData();
                    }}
                  >
                    展开
                    <RightOutlined />
                  </div>
                ) : (
                  <div
                    className="expandIconCpe"
                    onClick={() => {
                      setActive(!active);
                    }}
                  >
                    收起
                    <DownOutlined />
                  </div>
                )}
              </div>
            </Row>
          </div>
          <div
            className={
              active ? 'collapse-item-content-active' : 'collapse-item-content-hide'
            }
          >
            {/* 面板内容,可以自定义,我这里是封装了一个表格组件 用ref绑定 */}
            <TableList ref={tableRef} />
          </div>
        </div>
      );
    }
    
    
    

    样式css:

    .collapse-item {
      border-bottom: 1px solid rgba(5, 5, 5, 6%);
      border-radius: unset;
    	
      .collapse-item-header {
        position: relative;
        padding: 12px 16px;
        color: rgba(0, 0, 0, 88%);
        cursor: pointer;
    
        .expand {
          font-size: 12px;
          position: absolute;
          right: 16px;
        }
    
        .expandIconCpe {
          color: #0065ff !important;
        }
      }
    
      .collapse-item-content-hide {
        display: none;
      }
    
      .collapse-item-content-active {
        display: block;
        background-color: #fff;
      }
    
      .ant-table-tbody > tr:last-child > td {
        border-bottom: none;
      }
     .ant-row {
        flex-wrap: nowrap;
        word-break: break-all;
      }
    }
    
    

    面板内容组件中写接口请求,使用 forwardRef + useImperativeHandle让父组件调用子组件的方法。

    核心代码:

    
    import { forwardRef, useImperativeHandle} from 'react';
    
    interface TableRef {
      handleGetData: (params: any) => void;
    }
    const TableList = forwardRef<TableRef>((props, ref) => {
    
      // 子组件中
      useImperativeHandle(ref, () => ({
      // handleGetData是暴露给父组件的方法
      handleGetData: (params: any) => {
       // 这里可以自定义封装接口请求,然后渲染数据
       
       },
     }));
    })
    
    export default TableList;
    
    

    Tips:
    为了提高性能,不让每次点击展开都去发起请求,可以在请求成功一次结果后,设置一个标记,下次再点击展开时,判断如果已经标记请求成功过了,就不发起请求,展示上一次结果。

  • 相关阅读:
    JAVA JVM 是怎么判定对象已经“死去”?
    汇付国际亮相第五届进博会“2022贸易数字化促进跨境电商发展论坛”
    【scrapy、flask】如何在社区版 PyCharm 中调试 scrapy爬虫和 flask web 服务
    C++每日面试之assert()
    Ubuntu的SELinux
    21天打卡挑战学习MySQL——《Docker容器安装》第三周 第七篇
    Java Reflection构造器的示例简介说明
    时间复杂度为 O(n^2) 的排序算法
    Javaweb之Vue指令的详细解析
    uni-app实现点击显示隐藏列表,兼容微信小程序
  • 原文地址:https://blog.csdn.net/yqdid/article/details/139828068