Hi! 这里是在学习 React 的 JustHappy ,相信你和我一样,对 React 的 Hooks 早有耳闻。可以说 Hooks 的出现使得 React 的编写方式有了革命性的飞跃:更加接近原生 JS、更加灵活、复用性更高......所以话不多说,我们开始吧!
同样我们也会对比着 Vue 来讲解,一共要聊 8 个常用的 Hooks,上篇我们聊了 4 个,这篇我们把剩下的聊完吧!

有没有可能在数据变化之前干些事情?------ useReducer
在 React 中,useReducer
可以理解为一个 更可控的数据流管理工具 。
它把数据的修改逻辑集中到了一个地方(也就是 reducer 函数中),这让数据变化变得可预测、清晰,非常适合用于状态复杂、状态之间有明确逻辑的组件中。
比如:
jsx
import { useReducer } from 'react';
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
default:
return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<>
<div>{state.count}</div>
<button onClick={() => dispatch({ type: 'increment' })}>加1</button>
</>
);
}
我们通过 dispatch
发出一个动作(action),然后交由 reducer 去判断接下来要怎么更新 state,这种模式和 Redux 是一脉相承的。
React 中如何实现"依赖注入"?------ useContext
在前端开发中,依赖注入(Dependency Injection) 是一种用于管理组件之间数据共享 的方式,核心目的就是:避免层层传 props,提高组件间解耦能力。
Vue 中的依赖注入(provide/inject
)
Vue 提供 provide
和 inject
来帮助我们实现在祖先组件中提供数据,在后代组件中注入使用:
html
<!-- 父组件 -->
<script setup>
import { provide, ref } from 'vue';
const themeColor = ref('blue');
provide('theme', themeColor);
</script>
<template>
<ChildComponent />
</template>
html
<!-- 子组件 -->
<script setup>
import { inject } from 'vue';
const theme = inject('theme');
</script>
<template>
<div :style="{ color: theme }">这是一个主题颜色文本</div>
</template>
React 中的 useContext
React 提供的 useContext
Hook 也是实现依赖共享的关键工具,搭配 Context.Provider
使用:
jsx
import { createContext, useContext } from 'react';
const ThemeContext = createContext('blue');
function ChildComponent() {
const theme = useContext(ThemeContext);
return <div style={{ color: theme }}>这是一个主题颜色文本</div>;
}
function App() {
return (
<ThemeContext.Provider value="blue">
<ChildComponent />
</ThemeContext.Provider>
);
}
总结:React 的
useContext
和 Vue 的provide/inject
思路类似,都是从顶层组件注入数据,让深层组件可以直接访问,避免层层传 props 的痛苦。
memo + useMemo + useCallback ------ 那些和"缓存优化"有关的事情
性能优化是 React 开发中绕不开的话题,尤其在组件层级较深、状态更新频繁时,我们需要避免不必要的渲染 ,这个时候 memo
、useMemo
和 useCallback
就登场了!
React.memo
:组件层级的缓存
React.memo
是一个高阶组件,可以缓存一个函数组件的渲染结果,只有在 props 变化时才会重新渲染。
js
const Child = React.memo(({ name }) => {
console.log('子组件渲染');
return <div>Hello, {name}</div>;
});
使用前提:组件是纯函数组件,且 props 变化频率不高。
useMemo
:缓存计算结果
useMemo
用于缓存一个计算值,只有当依赖项变化时才会重新计算。
ini
const result = useMemo(() => {
return heavyCalculation(data);
}, [data]);
适用于复杂计算、数据处理(如排序、过滤等),避免每次渲染都重新计算。
useCallback
:缓存函数引用
useCallback
返回一个稳定的函数引用 ,可以避免因为父组件更新导致子组件重复渲染(尤其和 React.memo
配合使用)。
js
const handleClick = useCallback(() => {
console.log('clicked');
}, []);
和 useMemo(fn, deps)
类似,但 useCallback
返回的是函数本身。
它们的区别?
Hook | 缓存对象 | 何时使用 |
---|---|---|
React.memo |
缓存组件结果 | props 不变就不重新渲染组件 |
useMemo |
缓存计算值 | 计算开销大,值经常被重复使用时 |
useCallback |
缓存函数引用 | 避免子组件重复渲染、依赖变动频繁 |
总结一句话:
性能优化从来不是无脑加 Hook,而是在你清楚它的"副作用"和"价值"的前提下再用。