📌 基础hooks:
1. useState - 状态管理:
类似于 vue3 的 ref/reactive
import { useState } from 'react';
const [state, setState] = useState(initialValue);
通过 setState 改变 state 的值或者状态
useState允许传:
基本类型:String、Number、Boolean、null、undefined
引用类型:Array、Object、new Map()、new Set()、new Date()
函数(惰性初始化):仅在首次渲染时执行一次
如果传函数形式,则是惰性初始化
const [user, setUser] = useState(() => ({ name: 'John', age: 25 }));
这样写的特点是,函数只在首次渲染时执行一次,之后不再执行,适合用于计算成本比较高的初始值
但是如果直接写对象,那么每次渲染页面都会执行初始值
除此之外,还可以这样用:
const [data, setData] = useState(() => expensiveCalculation());
const expensiveCalculation = () => {
let result = 0;
for (let i = 0; i < 1000000; i++) {
result += Math.random();
}
return { value: result };
}
2. useEffect - 监听数据变化 / 清除副作用:
类似于 vue3 的 watch/watchEffect
useEffect:异步执行,不阻塞浏览器绘制
useLayoutEffect:同步执行,阻塞浏览器绘制
1. useEffect有三种写法:
useEffect(fn) => 不传依赖数组:
执行时机:每次渲染后执行,类似于 vue3 的 watchEffect,主要用于:开发调试,监听所有响应式数据的变化
useEffect(() => {
console.log('每次组件渲染后都会执行');
});
useEffect(fn, []) => 空数组[]:componentDidMount
执行时机:仅组件挂载时执行一次,类似于vue3 的 onMounted + onUnmounted,主要用于:初始化操作,事件监听,订阅
如果useEffect中只写一个return,什么都不写,那么它的作用是清除副作用:
useEffect(() => {
const timer = setInterval(() => {
console.log('定时器执行');
}, 1000);
// 清理函数:组件卸载或依赖变化前执行
return () => {
clearInterval(timer);
console.log('清理定时器');
};
}, []);
useEffect(fn, [dep1, dep2, ……]) => 有依赖的数组:componentDidUpdate
执行时机:依赖项变化时执行,类似于 vue3 的 watch([dep1, dep2], callback),主要用于:监听props值的变化,指定数据变化时监听执行
const [user, setUser] = useState(null);
useEffect(() => {
// 当 userId 变化时获取用户数据
fetchUserData(userId).then(data => setUser(data));
}, [userId]); // 依赖 userId
2. 关于useEffect的常用使用场景:
2.1. 数据获取:
2.2. 事件监听:
数据挂载与通过清除副作用卸载 => onMounted + onUnmounted
useEffect(() => {
const handleResize = () => {
setWindowSize({
width: window.innerWidth,
height: window.innerHeight
});
};
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
2.3. DOM操作:
useEffect(() => {
const modal = document.getElementById('modal');
if (isOpen) {
modal.style.display = 'block';
document.body.style.overflow = 'hidden';
}
return () => {
modal.style.display = 'none';
document.body.style.overflow = 'auto';
};
}, [isOpen]);
2.4. 订阅外部数据源:
useEffect(() => {
const subscription = dataSource.subscribe(data => {
setData(data);
});
return () => {
subscription.unsubscribe();
};
}, []);
除此之外,useEffect还用于实现:表单验证,防抖搜索等
3. useContent - 跨组件通讯:
类似于 vue3 的 provide/inject