一. useEffect(() => { ... }, [deps])
参数1:副作用函数
参数2:依赖数组,当依赖变化时重新执行:
[] 空数组 = 只在组件挂载时执行一次(相当于 Vue 的 mounted) [form] = 当 form 变化时执行
1. 空数组 [] = mounted(只执行一次)
// ========== React ==========
useEffect(() => {
console.log('只在组件挂载时执行一次')
}, []) // ⬅️ 空数组
// ========== Vue 对应 ==========
mounted() {
console.log('只在组件挂载时执行一次')
}
2.有值 [count] = mounted + watch(⚠️ 重点!)
// ========== React ==========
useEffect(() => {
console.log('执行了')
}, [count]) // ⬅️ 有依赖
// 执行时机:
// 1️⃣ 组件首次挂载时 → 执行
// 2️⃣ count 变化时 → 执行
对应 Vue 是:
// ========== Vue 2 - 需要 mounted + watch ==========
mounted() {
console.log('执行了') // 1️⃣ 首次执行
},
watch: {
count() {
console.log('执行了') // 2️⃣ count 变化时执行
}
}
// ========== 或者 watch + immediate ==========
watch: {
count: {
handler() {
console.log('执行了')
},
immediate: true // ⬅️ 让 watch 在首次也执行
}
}
3. 关键区别图解
// ========== React useEffect ==========
useEffect(() => {
console.log('count:', count)
}, [count])
// 时间轴:
// 组件挂载 → 执行 ✅(打印 count: 0)
// count 变为 1 → 执行 ✅(打印 count: 1)
// count 变为 2 → 执行 ✅(打印 count: 2)
// ========== Vue 2 默认的 watch ==========
watch: {
count() {
console.log('count:', this.count)
}
}
// 时间轴:
// 组件挂载 → 不执行 ❌
// count 变为 1 → 执行 ✅(打印 count: 1)
// count 变为 2 → 执行 ✅(打印 count: 2)
4. 实际例子
// ========== 登录页面的 useEffect ==========
const [count, setCount] = useState(0)
useEffect(() => {
console.log('当前 count:', count)
}, [count])
// 执行流程:
// 1. 组件首次渲染 → 打印 "当前 count: 0" ⬅️ 这是 mounted
// 2. 点击按钮 setCount(1) → 打印 "当前 count: 1" ⬅️ 这是 watch
// 3. 点击按钮 setCount(2) → 打印 "当前 count: 2" ⬅️ 这是 watch
// ========== Vue 2 需要两个钩子 ==========
data() {
return { count: 0 }
},
mounted() {
console.log('当前 count:', this.count) // 首次执行
},
watch: {
count(newVal) {
console.log('当前 count:', newVal) // 后续变化执行
}
}
// 或者用 immediate
watch: {
count: {
handler(newVal) {
console.log('当前 count:', newVal)
},
immediate: true // 首次也执行
}
}
5. 完整对照表
6. 三种情况总结
情况 1: 空数组
useEffect(() => {
console.log('初始化')
}, [])
✅ = Vue 的 mounted() (完全相同)
---
情况 2: 有依赖
useEffect(() => {
console.log('监听')
}, [count])
⚠️ = Vue 的 mounted() + watch (不完全相同)
区别:
- React: 首次就执行
- Vue watch: 默认首次不执行(除非加 immediate: true)
---
情况 3: 无第二参数
useEffect(() => {
console.log('每次渲染都执行')
}) // ⬅️ 没有第二个参数
= Vue 的 updated() 或 Vue 3 的 watchEffect()
---
记忆口诀
useEffect(() => {}, []) // 空数组 = mounted(挂载)
useEffect(() => {}, [count]) // 有值 = mounted + watch(挂载 + 监听)
useEffect(() => {}) // 没有 = updated(每次更新)
所以你的理解:
- ✅ 空数组 = mounted 正确!
- ⚠️ 有值 = watch 不完全准确,应该是 mounted + watch