【实战】 六、用户体验优化 - 加载中和错误状态处理(下) —— React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目(十)

文章目录

    • 一、项目起航:项目初始化与配置
    • 二、React 与 Hook 应用:实现项目列表
    • 三、TS 应用:JS神助攻 - 强类型
    • 四、JWT、用户认证与异步请求
    • 五、CSS 其实很简单 - 用 CSS-in-JS 添加样式
    • 六、用户体验优化 - 加载中和错误状态处理
      • 1~2
      • 3
      • 4.用useAsync获取用户信息
      • 5.实现 Error Boundaries,捕获边界错误


学习内容来源:React + React Hook + TS 最佳实践-慕课网


相对原教程,我在学习开始时(2023.03)采用的是当前最新版本:

版本
react & react-dom^18.2.0
react-router & react-router-dom^6.11.2
antd^4.24.8
@commitlint/cli & @commitlint/config-conventional^17.4.4
eslint-config-prettier^8.6.0
husky^8.0.3
lint-staged^13.1.2
prettier2.8.4
json-server0.17.2
craco-less^2.0.0
@craco/craco^7.1.0
qs^6.11.0
dayjs^1.11.7
react-helmet^6.1.0
@types/react-helmet^6.1.6
react-query^6.1.0
@welldone-software/why-did-you-render^7.0.1
@emotion/react & @emotion/styled^11.10.6

具体配置、操作和内容会有差异,“坑”也会有所不同。。。


一、项目起航:项目初始化与配置

  • 一、项目起航:项目初始化与配置

二、React 与 Hook 应用:实现项目列表

  • 二、React 与 Hook 应用:实现项目列表

三、TS 应用:JS神助攻 - 强类型

  • 三、 TS 应用:JS神助攻 - 强类型

四、JWT、用户认证与异步请求

  • 四、 JWT、用户认证与异步请求(上)

  • 四、 JWT、用户认证与异步请求(下)

五、CSS 其实很简单 - 用 CSS-in-JS 添加样式

  • 五、CSS 其实很简单 - 用 CSS-in-JS 添加样式(上)

  • 五、CSS 其实很简单 - 用 CSS-in-JS 添加样式(下)

六、用户体验优化 - 加载中和错误状态处理

1~2

  • 六、用户体验优化 - 加载中和错误状态处理(上)

3

  • 六、用户体验优化 - 加载中和错误状态处理(中)

4.用useAsync获取用户信息

修改 src\components\lib.tsx(新增全屏 Loading 组件 和 全屏 Error 展示组件):

import { Spin, Typography } from "antd";
import { DevTools } from "jira-dev-tool";...
const FullPage = styled.div`height: 100vh;display: flex;justify-content: center;align-items: center;
`export const FullPageLoading = () => <FullPage><Spin size="large"/>
</FullPage>export const FullPageErrorFallback = ({error}: {error: Error | null}) => <FullPage><DevTools/><Typography.Text type="danger">{error?.message}</Typography.Text>
</FullPage>
  • 为了展示报错信息的同时,DevTools 依旧展示,需要引入

修改 src\context\auth-context.tsx(使用 useAsync 改造,并新增全屏 Loading 组件 和 全屏 Error 展示组件)(部分未修改内容省略):

...
import { useAsync } from "utils/use-async";
import { FullPageErrorFallback, FullPageLoading } from "components/lib";...export const AuthProvider = ({ children }: { children: ReactNode }) => {// 这里要考虑到初始值的类型与后续值类型,取并组成一个泛型// const [user, setUser] = useState<User | null>(null);const { data: user, error, isLoading, isReady, isSuccess, isError, run, setData: setUser } = useAsync<User | null>()...useMount(() => run(initUser()));if (isReady || isLoading) {return <FullPageLoading/>}if (isError) {return <FullPageErrorFallback error={error}/>}return (...);
};
...

查看效果:完美!

5.实现 Error Boundaries,捕获边界错误

修改 src\unauthenticated-app\index.tsx(新增一个“抛出异常”按钮):

...
export const UnauthenticatedApp = () => {...return (<Container><Header /><Background /><Button onClick={() => {throw new Error('点击抛出一个异常')}}>抛出异常</Button><ShadowCard>...</ShadowCard></Container>);
};
...

修改 src\authenticated-app.tsx(新增一个变量展示它不存在的一个属性):

...
export const AuthenticatedApp = () => {...const value: any = undefined;...return (<Container>{ value.notExist }...</Container>);
};
...

编译代码并全局安装推荐的 serve 库,然后启动并访问:

npm run build
yarn global add serve
serve -s build

点击“抛出异常”按钮:

  • 测试环境:页面展示抛出异常
  • 生产环境:页面不变,控制台抛出异常

登录后:

  • 测试环境:页面展示异常信息
  • 生产环境:页面空白,控制台打印出异常信息

这两种异常对比可看出:在渲染阶段出现未被捕获的异常,整个组件树都会被卸载(错误的展示内容比空白内容更可怕)

  • 错误边界 – React

接下来写一个错误边界捕获组件 —— 新建:src\components\error-boundary.tsx

import React, { ReactNode } from "react";type FallbackRender = (props: { error: Error | null }) => React.ReactElement// children: ReactNode
export class ErrorBoundary extends React.Component<React.PropsWithChildren<{fallbackRender: FallbackRender}>, { error: Error | null }> {state = { error: null }// 当子组件抛出异常,这里会接受到并更改 statestatic getDerivedStateFromError(error: Error) {return { error }}render() {const { error } = this.stateconst { fallbackRender, children } = this.propsreturn error ? fallbackRender({ error }) : children}
}
  • 如果一个 class 组件中定义了 static getDerivedStateFromError()componentDidCatch() 这两个生命周期方法中的任意一个(或两个)时,那么它就变成一个错误边界
  • React.PropsWithChildrenReact 中的一个 Utility Types (工具类型) 类型处理器,将传入属性以类似 Object.assign 的方式合并:
    • type PropsWithChildren<P = unknown> = P & { children?: ReactNode | undefined };

修改:src\App.tsx(使用错误边界组件 ErrorBoundary 包裹,并将异常展示在 FullPageErrorFallback 中):

...
import { ErrorBoundary } from "components/error-boundary";
import { FullPageErrorFallback } from "components/lib";function App() {...return (<div className="App"><ErrorBoundary fallbackRender={FullPageErrorFallback}>{user ? <AuthenticatedApp /> : <UnauthenticatedApp />}</ErrorBoundary></div>);
}
...

重新编译代码并重启serve,然后访问:

npm run build
serve -s build

手动抛出错误还是原样,渲染异常导致的边界错误被截获并展示!

Cannot read property 'notExist' of undefined

测试过程中可能会需要清除 localStorage:

在这里插入图片描述

测试结束后清除以下两个文件中的测试内容(“抛出异常”按钮 和 “value”):

  • src\unauthenticated-app\index.tsx
  • src\authenticated-app.tsx

部分引用笔记还在草稿阶段,敬请期待。。。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

加密劫持者攻击教育机构

我们的专家分析了2023年第一季度的当前网络威胁。研究表明&#xff0c;独特事件的数量增加&#xff0c;勒索软件活动激增&#xff0c;特别是针对学术和教育机构。我们记录了大量与就业有关的网络钓鱼邮件&#xff0c;出现了QR网络钓鱼和恶意广告的增加。 我们的研究表明&#…

计算机组成原理课程论文: Intel 80386/80486 的体系架构调研

摘要 本文以Intel 80386/80486体系架构为研究对象&#xff0c;详细介绍了该体系架构的基本概念、特点和优势&#xff0c;分析了其在不同领域的应用情况&#xff0c;并对其未来的发展做出一定的展望和评价。 首先&#xff0c;我们介绍了研究背景和目的&#xff0c;阐述了Intel 8…

windows安装docker

目录 安装docekr Desktop下载安装 解决WSL 问题启用适用于 Linux 的 Windows 子系统检查运行 WSL 2 的要求启用虚拟机功能下载 Linux 内核更新包将 WSL 2 设置为默认版本 运行-可视化界面 安装docekr Desktop 下载 下载地址 Install Docker Desktop on Windows | Docker Docum…

攻防世界-web-ics-05

题目描述: 其他破坏者会利用工控云管理系统设备维护中心的后门入侵系统 题目链接点进去如下&#xff1a; 可以看到界面上有一个设备维护中心&#xff0c;点击设备维护中心&#xff0c;跳转到如下界面 再次点击&#xff0c;发现变成这样了 1. 思路分析 从已知信息来看&#xf…

算法与数据结构(一)--算法复杂性

一.算法复杂性的概念 算法的复杂性是指运行算法所需要的计算机资源的量。需要的时间资源的量称为时间复杂性&#xff0c;需要的空间资源的量称为空间复杂性。 这个量应该集中反映算法的效率&#xff0c;而从运行该算法的实际计算机中抽象出来。换句话说&#xff0c;这个量应该…

【算法集训之线性表篇】Day 08

文章目录 题目基本设计思想思路一思路二 代码实现效果 题目 已知一个整数数列A{a0,a1,a2,…,an-1}&#xff0c;其中0<ai<n(0<i<n)。若存在ap1ap2ap3…apmx且m>n/2(0<pk<n,1<k<m)&#xff0c;则成x为A的主元素。例如A{0,5,5,3,5,7,5,5}&#xff0c;…

【后端面经-架构】RabbitMQ简介

【后端面经-架构】RabbitMQ简介 1. MQ介绍2. RabbitMQ2.1 简介2.2 架构&#xff1a;组件解释2.3 特点2.4 优缺点 面试模拟参考资料 1. MQ介绍 MQ&#xff08;Message Queue&#xff09;用于在应用程序之间相互通信&#xff0c;在消息中发送数据进行通信&#xff0c;而不需要特…

【视觉SLAM入门】3. 相机模型,内外参,畸变推导

"瑾瑜匿瑕" 1. 相机模型和内参1.1 内参推导1.2 外参推导 2. 畸变2.1 径向畸变2.2 切向畸变 3. 深度信息3.1 算法测距3.2 物理测距 本节讨论围绕这个问题展开 机器人如何观测外部世界&#xff1f; \quad\large\textcolor{red}{机器人如何观测外部世界&#xff1f;} 机…

C++结合EasyX写扫雷(new)

【游戏】C结合EasyX写扫雷&#xff08;时隔半年后重写&#xff09; 上一次写扫雷这一次实现思路设置全局变量Grid类Grid类的成员函数启动画面死循环监听鼠标事件 全部代码其他 上一次写扫雷 大约半年之前的寒假期间&#xff0c;我接触了EasyX这个图形库&#xff0c;于是试着写…

数据结构--树和森林的遍历

数据结构–树和森林的遍历 树的先根遍历 void PreOrder(TreeNode* R) {if (R ! NULL){visit(R);while (R还有下一个子树T)PreOrder(T);} }树和二叉树的转化后》 树的先根遍历序列与这棵树相应二叉树的先序序列相同。 \color{red}树的先根遍历序列与这棵树相应二叉树的先序序列相…

串口的再认识

常用函数介绍 串口发送/接收函数 HAL_UART_Transmit(); 串口发送数据&#xff0c;使用超时管理机制&#xff08;即在发送成功前一直阻塞&#xff09; HAL_UART_Receive(); 串口接收数据&#xff0c;使用超时管理机制 HAL_UART_Transmit_IT(); 串口中断模式发送 HAL_UART…

C++ 变量类型

C 变量类型 变量其实只不过是程序可操作的存储区的名称。 在 C 中&#xff0c;有多种变量类型可用于存储不同种类的数据。 C 中每个变量都有指定的类型&#xff0c;类型决定了变量存储的大小和布局&#xff0c;该范围内的值都可以存储在内存中&#xff0c;运算符可应用于变量…