cccs7 Lv5

#处理数据加载和空状态渲染

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import { useState, useEffect } from 'react';

const DataComponent = () => {
// 定义三个核心状态:数据、加载状态、错误信息
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);

useEffect(() => {
const fetchData = async () => {
try {
// 发起 API 请求
const response = await fetch('https://api.example.com/data');
if (!response.ok) throw new Error('请求失败');

const result = await response.json();
setData(result);
} catch (err) {
setError(err.message);
} finally {
setIsLoading(false);
}
};

fetchData();
}, []); // 空依赖数组表示只执行一次

// 处理加载状态
if (isLoading) {
return <div className="loading-spinner">加载中...</div>;
}

// 处理错误状态
if (error) {
return <div className="error-message">错误:{error}</div>;
}

// 处理空数据状态(根据数据类型判断)
if (!data || (Array.isArray(data) && data.length === 0)) {
return <div className="empty-state">暂无数据</div>;
}

// 正常渲染数据
return (
<div className="data-list">
{data.map(item => (
<div key={item.id} className="data-item">
{item.name}
</div>
))}
</div>
);
};

export default DataComponent;

关键点解析:

  1. 状态管理

    • data: 存储从后端获取的数据(初始值为 null)

    • isLoading: 跟踪请求状态(避免渲染不完整数据)

    • error: 捕获并显示错误信息

  2. 生命周期控制

    • 使用 useEffect 处理副作用(数据获取)

    • 异步请求使用 async/await 语法

    • finally 确保最终都会关闭 loading 状态

  3. 条件渲染优先级

    1. 加载状态优先显示

    2. 错误状态次优先

    3. 空数据状态检查

    4. 最终数据渲染

  4. 空数据判断优化: ================

    • 数组数据检查 length

    • 对象数据检查 Object.keys(data).length

    • 根据业务需求自定义空状态条件

优化方案
useEffect 中 添加请求取消逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 在 useEffect 中添加请求取消逻辑
useEffect(() => {
const abortController = new AbortController();

const fetchData = async () => {
try {
const response = await fetch('https://api.example.com/data', {
signal: abortController.signal
});
// ...后续处理
} catch (err) {
if (err.name !== 'AbortError') {
// 处理非取消错误
}
}
};

fetchData();

return () => abortController.abort();
}, []);

#List防空渲染

1
2
3
4
5
6
7
8
9
10
11
{Array.isArray(labelList) && labelList.length > 0 ? (
labelList.map((label) => (
<h3
className='p-1 hover:rounded-md hover:bg-[#262626] cursor-pointer'
key={label.id}
onClick={() => console.log(label.id)}
>{label.labelName}</h3>
))
) : (
<div className="empty w-full"></div>
)}
  • Title:
  • Author: cccs7
  • Created at : 2025-04-10 23:01:04
  • Updated at : 2025-03-22 01:44:25
  • Link: https://cs7eric.github.io/2025/04/10/React/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments
On this page