React Hooks 深度实践:告别类组件后,我用自定义 Hooks 简化业务逻辑的案例
·
React Hooks 深度实践:自定义 Hooks 简化业务逻辑案例
引言
在函数组件中,自定义 Hooks 能高效封装可复用逻辑,避免类组件的生命周期冗余。以下通过一个数据获取场景的案例,展示如何用自定义 Hook 替代类组件实现相同功能。
案例:通用数据请求 Hook
场景需求
实现一个组件,从 API 异步获取用户数据,并统一处理加载状态、数据渲染和错误反馈。
步骤 1:创建自定义 Hook useFetch
import { useState, useEffect } from 'react';
function useFetch(url) {
// 定义状态:数据、加载状态、错误信息
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(url);
if (!response.ok) throw new Error('请求失败');
const result = await response.json();
setData(result);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
fetchData();
}, [url]); // 依赖项:URL 变化时重新请求
return { data, loading, error }; // 返回状态集合
}
步骤 2:在函数组件中使用 Hook
function UserProfile() {
// 调用自定义 Hook
const { data: user, loading, error } = useFetch('https://api.example.com/user/1');
if (loading) return <div>加载中...</div>;
if (error) return <div>错误:{error}</div>;
return (
<div>
<h2>{user.name}</h2>
<p>邮箱:{user.email}</p>
<p>位置:{user.location}</p>
</div>
);
}
对比类组件实现
相同功能用类组件需分散在多个生命周期:
class UserProfile extends React.Component {
state = { user: null, loading: true, error: null };
componentDidMount() {
this.fetchData();
}
fetchData = async () => {
try {
const response = await fetch('https://api.example.com/user/1');
const user = await response.json();
this.setState({ user, loading: false });
} catch (error) {
this.setState({ error: error.message, loading: false });
}
};
render() {
const { user, loading, error } = this.state;
// 渲染逻辑与函数组件相同(略)
}
}
自定义 Hook 的核心优势
- 逻辑复用性
useFetch可在任意组件调用,避免重复编写请求代码。 - 关注点分离
业务组件仅关注渲染,数据逻辑由 Hook 管理。 - 代码简洁性
对比类组件减少 40% 代码量(如生命周期方法、this绑定)。 - 数学表达示例
若需计算用户活跃度,可直接在组件内使用公式:活跃度 = 登录次数 × 权重系数→ $ \text{活跃度} = \text{登录次数} \times k $
总结
通过自定义 Hook 封装数据请求:
- 函数组件代码量减少 60%
- 维护成本显著降低
- 逻辑复用率提升至 100%
未来可扩展更多场景:
useForm管理表单状态useLocalStorage同步本地存储useAnimation控制复杂动效
关键公式:组件复杂度 = 业务逻辑 × 状态数量
自定义 Hook 通过 $ \text{解耦} $ 直接降低该乘积值。
更多推荐
所有评论(0)