React Hooks 最佳实践指南
React Hooks 自 16.8 版本引入以来,已经成为现代 React 开发的标准。本文总结了一些重要的最佳实践。
1. useState 优化
使用函数式更新
// ❌ 避免
setCount(count + 1);
// ✅ 推荐
setCount(prev => prev + 1);
合理拆分状态
// ❌ 避免把所有状态放在一个对象中
const [state, setState] = useState({
name: '',
email: '',
age: 0,
// ... 更多字段
});
// ✅ 推荐按逻辑分组
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [userInfo, setUserInfo] = useState({ age: 0 });
2. useEffect 最佳实践
正确设置依赖数组
// ❌ 遗漏依赖
useEffect(() => {
fetchUserData(userId);
}, []); // 缺少 userId 依赖
// ✅ 包含所有依赖
useEffect(() => {
fetchUserData(userId);
}, [userId]);
清理副作用
useEffect(() => {
const timer = setInterval(() => {
// 定时器逻辑
}, 1000);
// 清理函数
return () => clearInterval(timer);
}, []);
3. 自定义 Hooks
提取可复用逻辑
// 自定义 Hook:本地存储
function useLocalStorage(key, initialValue) {
const [storedValue, setStoredValue] = useState(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
return initialValue;
}
});
const setValue = (value) => {
try {
setStoredValue(value);
window.localStorage.setItem(key, JSON.stringify(value));
} catch (error) {
console.error('Error saving to localStorage:', error);
}
};
return [storedValue, setValue];
}
4. 性能优化
使用 useMemo 和 useCallback
// 缓存计算结果
const expensiveValue = useMemo(() => {
return heavyCalculation(data);
}, [data]);
// 缓存函数引用
const handleClick = useCallback(() => {
onItemClick(item.id);
}, [item.id, onItemClick]);
React.memo 配合 Hooks
const MemoizedComponent = React.memo(({ items, onSelect }) => {
const handleSelect = useCallback((id) => {
onSelect(id);
}, [onSelect]);
return (
<div>
{items.map(item => (
<Item
key={item.id}
item={item}
onSelect={handleSelect}
/>
))}
</div>
);
});
5. 常见陷阱
闭包陷阱
// ❌ 问题代码
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
setCount(count + 1); // 总是使用初始值 0
}, 1000);
return () => clearInterval(timer);
}, []);
return <div>{count}</div>;
}
// ✅ 解决方案
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
setCount(prev => prev + 1); // 使用函数式更新
}, 1000);
return () => clearInterval(timer);
}, []);
return <div>{count}</div>;
}
总结
React Hooks 的关键是:
- 理解依赖数组的重要性
- 合理使用 memo 化技术
- 提取可复用的自定义 Hooks
- 注意闭包和异步更新的陷阱
掌握这些最佳实践,能让你的 React 应用更加健壮和高效。