react项目中封装一个通用的边界Boundary

# Boundary 

通用的边界,同时是一个Suspense 和一个 ErrorBoundary

正常情况不直接用,使用一下几个封装好的:

-Boundary.FullSizeLoading: 占满父容器全部高度,居中显示等待动画;

-Boundary.Loading: 占满一行,显示一个普通尺寸的等待动画;

-Boundary.Blank: 什么都不显示,加速速度足够快的话可以使用;

先看一下代码目录结构:

(1)index.tsx 

import {ComponentProps} from 'react';
import {Boundary as SuspenseBoundary,SuspenseBoundaryProps} from 'react-suspense-boundary';
import styled from '@emotion/styled';
import {times} from 'ramda';
import {Spin,Skeletion} from 'antd';
import {flexCenter} from './css/flex';
import fullSizeCenter from './FullSizeCenter/index';
import {defaultRenderError,defaultRenderFullSizeError} from './defaults';

interface Props extends SuspenseBoundaryProps{
    /**
     * 显示错误时是否占满整个容器
     */
    fullSize?:boolean;
}

function Boundary({fullSize =false,...props}:Props){
    return (
        <SuspenseBoundary 
           {...props}
           renderError={props.renderError ?? (fullSize ? defaultRenderFullSizeError : defaultRenderError)}
        />
    )
}

Boundary.FullSizeLoading = function FullSizeLoadingBoundary(props:SuspenseBoundaryProps){
    return (
        <Boundary 
            fullSize
            pendingFallback={
                <fullSizeCenter>
                    <Spin size="large" />
                </fullSizeCenter>
            }
        />
    )
}

export interface SkeletionProps extends SuspenseBoundaryProps,Omit<Components<typeof Skeletion>,'children'>{
    repeat?:number;
}

Boundary.Skeletion = function SkeletionBoundary({repeat=1,...props}:SkeletionProps){
    return (
        <Boundary 
            pendingFallback={
               <div>
                  {times(i => <Skeletion loading active key={i} {...props} />,repeat)}
               </div>
            }
            {...props}
        />
    )
}

Boundary.FullSizeSkeletion = function FullSizeSkeletionBoundary({repeat=1,...props}:SkeletionProps){
    return (
        <Boundary 
            fullSize
            pendingFallback={
                <fullSizeCenter>
                  {times(i => <Skeletion loading active key={i} {...props} />,repeat)}
                </fullSizeCenter>
            }
            {...props}
        />
    )
}

const LoadingContainer =styled.div`
    ${flexCenter};
    margin : 20px 0;
`

Boundary.Loading = function LoadingBoundary(props:SuspenseBoundaryProps){
    return(
        <Boundary 
          pendingFallback={
              <LoadingContainer>
                  <Spin />
              </LoadingContainer>
          }
          {...props}
        />
    )
}

Boundary.InlineLoading = function InlineLoadingBoundary(props:SuspenseBoundaryProps){
    return <Boundary pendingFallback={<Spin size="small" />} {...props} /> 
}

Boundary.Blank = function BlankBoundary(props:SuspenseBoundaryProps){
    return <Boundary pendingFallback={<fullSizeCenter />} {...props} /> 
}

export default Boundary;

 (2)defaults.tsx

inport Error from './Error';
import FullSizeCenter from './FullSizeCenter';

const renderErrorWithFullSize=(fullSize:boolean)=>(error:any)=>{
    const message = error?.message;
    const errorType=error?.responseStatus || '400';
    if(fullSize){
        return (
            <FullSizeCenter>
                <Error type={errorType} message={message} displayInDetail></Error>
            </FullSizeCenter>
        )
    } 
    return   <Error type={errorType} message={message} displayInDetail></Error>
}

export const defaultRenderError = renderErrorWithFullSize(false);
export const defaultRenderFullSizeError = renderErrorWithFullSize(true);

(3)Error/index.tsx

import {createElement} from 'react';
import {useToggle} from '@huse/boolean';
import {Empty,Gap,Button} from 'antd';
import FullSizeCenter from '../FullSizeCenter';
import ServerError from './ServerError.svg?react';
import ClientError from './ClientError.svg?react';
import Forbidden from './Forbidden.svg?react';
import NotFound from './NotFound.svg?react';

const STATUS_CODE_TO_COMPONENT={
    400:ClientError,
    403:Forbidden,
    404:NotFound,
    500:ServerError
};

const GENERAL_ERROR_MESSAGE='请求时出现错误';

const  STATUS_CODE_TO_MESSAGE={
    400:GENERAL_ERROR_MESSAGE,
    403:'无权限',
    404:'找不到指定页面',
    500:'未知的服务端错误',
}

interface Props{
    type?:'500' | '400' | '403' | '404';
    message?:string;
    displayInDetail?:boolean;
    className?:string;
};

export default function Error({type='400',message,displayInDetail,className}:Props){
    const [expand,toggle]=useToggle(false);
    const errorMessage = displayInDetail ? GENERAL_ERROR_MESSAGE : message;
    return (
        <FullSizeCenter style={{flexDirection:'cloumns'}}>
           <Empty 
            image={createElement(STATUS_CODE_TO_COMPONENT[type])}
            description={errorMessage ?? STATUS_CODE_TO_MESSAGE[type]}
            className={className}
           />
           {
               displayInDetail && (
                   <>
                      <Gap.Vertical factor={4} base={4} />
                      <Button type="link" onClick={toggle}>{expand ? '收起' : '查看详情'}</Button>
                      {
                          expand && (
                              <p style={{wordBreak:'break-all'}}>
                                {message}
                              </p>
                          )
                      }

                   <>
               )
           }
        </FullSizeCenter>
    )
}

 (4)FullSizeCenter/index.tsx

import styled from '@emotion/styled';
import fullSizeFlexCenter from '../css/flex';

const fullSizeCenter=styled.div`
${fullSizeFlexCenter}
`
export default fullSizeCenter;

(5)css/flex.ts

import {css} from '@emotion/react';

export const flexCenter =css`
display:flex;
align-items:center;
justify-content:center;
`

export const fullSizeFlexCenter =css`
${flexCenter}
width:100%;
height:100%;
min-height:inherit;
`

使用时,直接用封装好的边界组件来作为顶层组件来包裹其他组件,例如:

<Boundary.Loading >
   ...其他代码
</Boundary.Loading >

代码缺少几个状态码对应的svg,感兴趣的小伙伴自己可以找一下!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/608672.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Hadoop3:HDFS的Shell操作(常用命令汇总)

一、简介 什么是HDFS的Shell操作&#xff1f; 很简单&#xff0c;就是在Linux的终端&#xff0c;通过命令来操作HDFS。 如果&#xff0c;你们学习过git、docker、k8s&#xff0c;应该会发现&#xff0c;这些命令的特点和shell命令非常相似 二、常用命令 1、准备工作相关命令…

let命令

let 命令 let 与 var 二者区别&#xff1a; 作用域不同&#xff1a;变量提升&#xff08;Hoisting&#xff09;&#xff1a;临时性死区重复声明&#xff1a; 联系&#xff1a;举例说明&#xff1a; 块级作用域 块级作用域的关键字使用 var&#xff08;无块级作用域&#xff09;…

x64dbg中类似于*.exe+地址偏移

在CE和xdb中&#xff0c;形如*.exe数字偏移形式的地址被称为模块地址&#xff0c;CE附加到进程后点击查看内存&#xff0c;显示如下图 这种地址学名叫做模块地址&#xff0c;在x64dbg中显示如下图&#xff1a; CE中可以关闭&#xff0c;从而显示绝对的虚拟地址&#xff0c;如下…

Hive-URL解析函数

Hive-URL解析函数 1.实际工作需求 2.URL的基本组成 3.Hive中的Url解析函数 parse_url函数 parse_url_tuple函数

VScode通过ssh远程连接服务器被拒绝:permission denied, please try again

使用场景&#xff1a; 使用windows系统下的vscode远程连接服务器的linux系统&#xff0c;终端提示permission denied, please try again,但是使用cmd是可以远程登录的。 解决办法&#xff1a; 前提条件windows端的vscode安装了ssh远程连接的相关插件Remote - SSH&#xff0c;…

红米Turbo3小米平板6SPro澎湃OS系统强解BL锁-跳小米社区绑定-刷ROOT权限

红米Turbo3小米平板6SPro这2款设备都出厂为澎湃OS系统&#xff0c;官方提供都是小米社区申请解锁权限&#xff0c;然后自己答题解锁&#xff0c;门槛非常高&#xff0c;想要玩机root的用户&#xff0c;都在堵在门外。还在这目前这两款机型官方并没有加入强制验证&#xff0c;在…

何为基差?股指期货的升水和贴水又怎么理解?

基差是一个金融术语&#xff0c;它指的是现货价格和期货价格之间的差额。在股指期货市场中&#xff0c;现货就是指实际的股票指数&#xff0c;而期货则是基于这个指数未来某个时间点的价格预期。基差可以是正的或负的&#xff0c;具体取决于期货价格是高于还是低于现货价格。 1…

机器人种类分析

2000年前&#xff0c;机器人主要应用于工业生产&#xff0c;俗称工业机器人&#xff0c;由示教器操控&#xff0c;帮助工厂释放劳动力&#xff0c;此时的机器人并没有太多智能而言&#xff0c;完全按照人类的命令执行动作&#xff0c;更加关注电气层面的驱动器、伺服电机、减速…

Springboot集成Netflix-ribbon、Consul实现负载均衡调用-09

Consul简介 Consul是一个开源的服务发现和配置管理工具&#xff0c;具有跨平台、运行高效等特点。它由HashiCorp公司开发&#xff0c;并使用Go语言编写。Consul主要用于实现分布式系统中的服务发现、健康检查、键值存储等功能。 核心功能 服务发现&#xff1a;Consul通过DNS…

JavaScript百炼成仙自学笔记——13

函数七重关之六&#xff08;“new”一个函数&#xff09; 看个代码&#xff1a; function hello(){console.log(this); } 1、this&#xff1a;也是JavaScript中的一个关键字&#xff0c;永远指向当前函数的调用者 解释一下,有两层意思&#xff1a; ①this要嘛不出现&#…

基于SSM的“环卫工管理平台”的设计与实现(源码+数据库+文档+PPT)

基于SSM的“环卫工管理平台”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SSM 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统总体设计图 注册 首页 后台登录 后台页面 环卫工管理 摘…

mac安装 php7.1/apache

1. 安装php 7.1 brew tap shivammathur/php 查看可安装版本 brew search php 安装指定版本&#xff08;禅道适用PHP运行环境(7.0/7.1/7.2版本)&#xff09; brew install php7.1 环境配置 vim ~/.zshrc export PATH"/usr/local/opt/php7.1/bin:$PATH" export …

使用Postman进行接口测试---解析postman页面

一、Postman 是一款流行的 API 测试工具&#xff0c;它提供了丰富的功能来帮助开发者测试和调试 API。以下是 Postman 页面上的主要功能及其含义和作用&#xff1a; 1. 请求详情&#xff08;Request Details&#xff09; &#xff1a; - 方法&#xff08;Method&#xff0…

【读论文】Gaussian Grouping: Segment and Edit Anything in 3D Scenes

Gaussian Grouping: Segment and Edit Anything in 3D Scenes 文章目录 Gaussian Grouping: Segment and Edit Anything in 3D Scenes1. What2. Why3. How3.1 Anything Mask Input and Consistency3.2 3D Gaussian Rendering and Grouping3.3 Downstream: Local Gaussian Editi…

第二篇【AI与传奇开心果系列】Python的AI技术点库案例示例:详解AI工业应用算法原理

AI与传奇开心果系列博文 系列博文目录Python的AI技术点库案例示例系列 博文目录前言一、AI工业应用算法原理介绍二、机器学习在工业领域的应用算法示例代码三、深度学习算法在工业领域应用示例代码四、强化学习在工业领域应用示例代码五、自然语言处理在工业领域应用示例代码六…

C语言 变量的作用域

今天 我们来说变量的作用域和存储类型 每种事物 都有自己作用的范围限制 例如 汽车只能在路上跑 轮船只能在海洋 飞机只能通行于天空 函数的参数 也只有在函数被调用过程中分配内存资源 函数执行结束 空间也会被立即释放 这也说明了 行参变量只有在函数内才有效 离开了该函数 …

【JavaEE】博客系统(前端页面设计)

文章目录 一、预期效果二、实现博客列表页 一、预期效果 二、实现博客列表页 实现导航栏 编辑 blog_list.html, 创建导航栏的 html 代码. 导航栏里面包含 logo, 标题, 以及一些按钮(跳转链接). 为了实现左右排列, 在 logo 和 按钮 之间加一个 spacer 作为占位器. <!-- 导航…

初次查询大数据信用报告,需要注意哪些问题?

随着大数据的普及&#xff0c;基于大数据技术的大数据信用也变得越来越重要&#xff0c;比如在申贷之前&#xff0c;不少地方都会查询申贷人的大数据信用&#xff0c;作为风险控制的必要手段&#xff0c;那对于初次查询大数据信用报告的人来说&#xff0c;需要注意哪些问题呢?…

引领AI数据标注新纪元:景联文科技为智能未来筑基

在人工智能蓬勃发展的今天&#xff0c;数据如同燃料&#xff0c;驱动着每一次技术飞跃。在这场智能革命的浪潮中&#xff0c;景联文科技凭借其深厚的专业实力与前瞻性的战略眼光&#xff0c;正站在行业前沿&#xff0c;为全球的人工智能企业提供坚实的数据支撑。 全国布局&…

vscode的git插件使用教程

虽然git的命令我没有滚瓜烂熟&#xff0c;但vscode的git插件是尊嘟很好用啊&#xff0c;都被我用烂了。在网上看见一个讲的很不错的插件教程。借鉴一下。并在一些地方用块引用进行了补充说明&#xff01; 跳过了vscode安装过程。 克隆GitHub中的存储库&#xff1a; 1、复制Gi…