大家好,我是格子,今天我们来总结一下 React 与 Vue3 的 Hooks,方便我们记忆。
1. useState
作用:管理组件状态
参数:initialState
(初始状态)
返回值:[state, setState]
(当前状态和更新函数)
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}
Vue3 对应:ref
或 reactive
,相当于就是定义响应式数据
<script setup>
import { ref } from 'vue';
const count = ref(0);
</script>
<template>
<button @click="count++">{{ count }}</button>
</template>
差异:Vue 的响应式是自动根据定义的对象变化更新 DOM,但是 React 需手动调用 setState
(显式调用,从而更新 DOM)。
2. useEffect
作用:处理副作用(如 API 请求、DOM 操作)
参数:(effect, dependencies?)
(副作用函数和依赖数组)
useEffect(() => {
document.title = `Count: ${count}`;
}, [count]); // 仅在 count 变化时执行
// vue onBeforeUnmount、onMounted
useEffect(() => {
// 类似 vue onMounted
const timer = setInterval(() => {
console.log("Running...");
}, 1000);
// 类似 vue onBeforeUnmount
return () => {
clearInterval(timer); // 清理定时器
};
}, [dependencies]);
Vue3 对应:watchEffect
或 watch
当 useEffect
返回一个函数时, 则相当于 vue
的 onBeforeUnmount
组件卸载回调,并且 useEffect
首次执行时,相当于 onMounted
方法。
<script setup>
import { watchEffect } from 'vue';
watchEffect(() => {
document.title = `Count: ${count.value}`;
});
</script>
差异:Vue 自动收集依赖,React 需显式声明依赖数组。
3. useReducer
作用:复杂状态逻辑管理
参数:(reducer, initialState, init?)
const reducer = (state, action) => {
switch (action.type) {
case 'increment': return state + 1;
default: return state;
}
};
const [state, dispatch] = useReducer(reducer, 0);
Vue3 对应:reactive
+ 自定义函数 或 Pinia
<script setup>
import { reactive } from 'vue';
const state = reactive({ count: 0 });
const dispatch = (type) => {
if (type === 'increment') state.count++;
};
</script>
差异:Vue 更推荐组合式函数或 Pinia 管理复杂状态。
4. useMemo
作用:缓存计算结果
参数:(compute, dependencies)
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
Vue3 对应:computed
<script setup>
import { computed } from 'vue';
const memoizedValue = computed(() => a.value + b.value);
</script>
差异:Vue 的 computed
自动追踪依赖,React 需手动声明。
5. useCallback
作用:缓存函数引用
参数:(callback, dependencies)
const memoizedCallback = useCallback(() => doSomething(a), [a]);
Vue3 对应:直接使用函数 或 computed
<script setup>
const memoizedCallback = () => doSomething(a.value); // Vue 自动优化
</script>
差异:Vue 无需显式缓存函数,依赖响应式系统自动处理。
6. useContext
作用:跨组件传递数据
参数:Context
对象
const ThemeContext = createContext('light');
const theme = useContext(ThemeContext);
Vue3 对应:provide/inject
<!-- Parent -->
<script setup>
import { provide } from 'vue';
provide('theme', 'light');
</script>
<!-- Child -->
<script setup>
import { inject } from 'vue';
const theme = inject('theme');
</script>
差异:React 需显式 useContext
,Vue 通过 inject
直接获取。
7. useRef
作用:保存可变值或 DOM 引用
参数:initialValue
const inputRef = useRef(null);
<input ref={inputRef} />
Vue3 对应:ref
<script setup>
import { ref } from 'vue';
const inputRef = ref(null);
</script>
<template>
<input ref="inputRef" />
</template>
差异:Vue 的 ref
通过 .value
访问,React 通过 .current
。
8. useLayoutEffect
作用:与 useEffect
类似,但同步执行(在 DOM 更新后、浏览器绘制前)
useLayoutEffect(() => {
// 操作 DOM 元素
}, [deps]);
Vue3 对应:无直接等价,可通过 nextTick
模拟
<script setup>
import { nextTick } from 'vue';
nextTick(() => {
// DOM 更新后执行
});
</script>
9. useImperativeHandle
作用:自定义暴露给父组件的 ref 方法
参数:(ref, createHandle, dependencies?)
const MyInput = forwardRef((props, ref) => {
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => inputRef.current.focus()
}));
return <input ref={inputRef} />;
});
Vue3 对应:defineExpose
<!-- Child -->
<script setup>
defineExpose({ focus: () => inputRef.value.focus() });
</script>
差异:Vue 通过 defineExpose
直接暴露属性。
总结对比
React Hook | Vue3 对应 | 核心差异 |
---|---|---|
useState | ref /reactive | Vue 自动追踪依赖 |
useEffect | watchEffect /watch | Vue 自动收集依赖 |
useReducer | 组合式函数/Pinia | Vue 推荐模块化状态管理 |
useMemo /useCallback | computed | Vue 自动缓存 |
useContext | provide /inject | 语法差异,功能相似 |
useRef | ref | 访问方式不同(.current vs .value ) |
useLayoutEffect | nextTick | Vue 无直接等价 API |
useImperativeHandle | defineExpose | Vue 更简洁的暴露方式 |
React Hooks 强调显式声明依赖,Vue Composition API 依赖自动追踪,语法更简洁。