在前端开发的世界里,React 一直以其组件化、声明式的特性深受开发者喜爱。而自从 React 16.8 推出 Hooks(钩子函数)以来,函数组件的能力得到了极大提升,开发体验也变得更加丝滑。今天,我们就一起来深入了解 React Hooks 的核心用法,结合具体例子,轻松掌握它们的精髓,让你的代码更优雅、更高效!
一、什么是 Hooks?为什么要用 Hooks?
Hooks 是 React 官方为函数组件提供的一组"钩子"API,让你无需编写 class 组件,也能拥有状态管理、生命周期等强大功能。它们让代码更简洁、逻辑更清晰,极大提升了开发效率。
简单来说:
- 以前:只有 class 组件才能用 state、生命周期
- 现在:函数组件 + Hooks = 一切皆有可能!
二、常用 Hooks 的详解
1. useState ------ 让你的变量"活"起来
作用:为函数组件引入响应式状态变量。
用法:
js
import React, { useState } from 'react';
function Counter() {
// count 是当前状态,setCount 是修改状态的方法
const [count, setCount] = useState(0);
return (
<div>
<p>当前计数:{count}</p>
<button onClick={() => setCount(count + 1)}>点我+1</button>
</div>
);
}
小结:
useState
返回一个数组,包含当前状态和修改方法。- 每次调用 set 方法,组件会自动重新渲染。
小贴士:
- 可以用来管理表单输入、开关状态等各种场景。
2. useEffect ------ 副作用管理小能手
作用:处理副作用,比如数据请求、订阅、手动操作 DOM 等。
用法:
js
import React, { useState, useEffect } from 'react';
function DataLoader() {
const [data, setData] = useState([]);
useEffect(() => {
// 模拟请求数据
fetch('http://localhost:3000/data')
.then(res => res.json())
.then(json => setData(json));
}, []); // 依赖数组为空,表示只在组件挂载时执行一次
return (
<ul>
{data.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
);
}
小结:
- 依赖数组为空时,只在组件首次加载时执行。
- 依赖数组有值时,只有依赖变化才会执行。
- 可以返回一个清理函数,用于组件卸载时执行。
小贴士:
- 用于数据请求、事件监听、定时器等场景。
3. useLayoutEffect ------ 同步副作用的利器
作用 :与 useEffect
类似,但它会在 DOM 更新后、浏览器绘制前同步执行。
用法:
js
import React, { useLayoutEffect, useRef } from 'react';
function LayoutDemo() {
const divRef = useRef();
useLayoutEffect(() => {
divRef.current.style.color = 'red';
}, []);
return <div ref={divRef}>我是红色的文字</div>;
}
小结:
- 适合需要同步读取布局、强制同步修改 DOM 的场景。
- 一般情况下,优先用
useEffect
,只有特殊需求才用useLayoutEffect
。
4. useReducer ------ 复杂状态管理的好帮手
作用 :当状态逻辑复杂或多个状态相互关联时,推荐用 useReducer
。
用法:
js
import React, { useReducer } from 'react';
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<div>
<p>计数:{state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>加1</button>
<button onClick={() => dispatch({ type: 'decrement' })}>减1</button>
</div>
);
}
小结:
useReducer
接收 reducer 函数和初始 state。- 通过
dispatch
派发 action,reducer 返回新的 state。 - 适合表单、复杂交互等场景。
5. useRef ------ 获取 DOM 或保存变量
作用:获取 DOM 元素引用,或保存一个在组件生命周期内不会变化的变量。
用法:
js
import React, { useRef } from 'react';
function InputFocus() {
const inputRef = useRef();
const focusInput = () => {
inputRef.current.focus();
};
return (
<div>
<input ref={inputRef} placeholder="点按钮聚焦我" />
<button onClick={focusInput}>聚焦输入框</button>
</div>
);
}
小结:
useRef
返回一个可变的 ref 对象,.current
属性指向 DOM。- 也可用于保存定时器 id、上一次的 props/state 等。
6. useContext ------ 跨组件传值不再烦恼
作用:实现跨组件(祖孙、兄弟)间的数据共享,避免层层 props 传递。
用法:
js
import React, { createContext, useContext } from 'react';
const ThemeContext = createContext('light');
function ThemedButton() {
const theme = useContext(ThemeContext);
return <button style={{ background: theme === 'dark' ? '#333' : '#eee' }}>主题按钮</button>;
}
function App() {
return (
<ThemeContext.Provider value="dark">
<ThemedButton />
</ThemeContext.Provider>
);
}
小结:
- 先用
createContext
创建上下文,再用Provider
提供数据。 - 子组件用
useContext
获取数据,随时随地都能用!
三、实战小案例:数据列表的增删查
结合上面 Hooks,假如我们要做一个数据列表页面,支持加载、搜索、删除功能:
js
import React, { useState, useEffect } from 'react';
function DataList() {
const [data, setData] = useState([]);
const [keyword, setKeyword] = useState('');
// 加载数据
useEffect(() => {
fetch(`http://localhost:3000/data?name=${keyword}`)
.then(res => res.json())
.then(json => setData(json));
}, [keyword]);
// 删除数据
const handleDelete = id => {
fetch(`http://localhost:3000/data/${id}`, { method: 'DELETE' })
.then(() => setData(data.filter(item => item.id !== id)));
};
return (
<div>
<input
value={keyword}
onChange={e => setKeyword(e.target.value)}
placeholder="搜索..."
/>
<ul>
{data.map(item => (
<li key={item.id}>
{item.name}
<button onClick={() => handleDelete(item.id)}>删除</button>
</li>
))}
</ul>
</div>
);
}
是不是很简单?只用 useState
和 useEffect
就能搞定大部分需求啦!😄
四、总结
React Hooks 让函数组件变得更强大、更灵活。只要掌握了 useState
、useEffect
、useLayoutEffect
、useReducer
、useRef
和 useContext
这 6 个常用钩子,你就能轻松应对绝大多数开发场景。建议大家多动手实践,遇到问题多查文档,慢慢你也会成为 Hooks 大师!💪