React Hooks
外观
React Hooks 是 React 16.8 引入的一项特性,允许开发者在函数组件中使用状态(state)和其他 React 特性(如生命周期方法),而无需编写类组件。Hooks 提供了一种更简洁、更直观的方式来管理组件逻辑,同时保持代码的可复用性和可维护性。
简介[编辑 | 编辑源代码]
在 React 之前,函数组件是无状态的,只能作为“纯函数”使用。如果需要状态或生命周期方法,开发者必须使用类组件。Hooks 的出现改变了这一现状,使得函数组件能够拥有与类组件相同的功能。
Hooks 的核心思想是:
- **无需类组件**:直接在函数组件中使用状态和副作用。
- **逻辑复用**:通过自定义 Hooks 封装和复用组件逻辑。
- **更清晰的代码结构**:避免类组件中的复杂嵌套和生命周期方法。
基本 Hooks[编辑 | 编辑源代码]
useState[编辑 | 编辑源代码]
`useState` 是最基础的 Hook,用于在函数组件中添加局部状态。
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0); // 初始值为 0
return (
<div>
<p>当前计数: {count}</p>
<button onClick={() => setCount(count + 1)}>增加</button>
</div>
);
}
- `count`:当前状态值。
- `setCount`:更新状态的函数。
useEffect[编辑 | 编辑源代码]
`useEffect` 用于处理副作用(如数据获取、订阅、手动 DOM 操作等),相当于类组件中的 `componentDidMount`、`componentDidUpdate` 和 `componentWillUnmount` 的组合。
import React, { useState, useEffect } from 'react';
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setSeconds(prevSeconds => prevSeconds + 1);
}, 1000);
return () => clearInterval(interval); // 清理函数
}, []); // 空依赖数组表示只在组件挂载时执行
return <p>已运行: {seconds} 秒</p>;
}
- **依赖数组**(第二个参数):
* 空数组 `[]`:仅在组件挂载时运行一次。 * 包含变量 `[dep1, dep2]`:当依赖项变化时重新运行。
进阶 Hooks[编辑 | 编辑源代码]
useContext[编辑 | 编辑源代码]
`useContext` 用于在组件树中共享数据,避免逐层传递 props。
import React, { useContext } from 'react';
const ThemeContext = React.createContext('light');
function ThemedButton() {
const theme = useContext(ThemeContext);
return <button style={{ background: theme === 'dark' ? '#333' : '#fff' }}>按钮</button>;
}
useReducer[编辑 | 编辑源代码]
`useReducer` 是 `useState` 的替代方案,适用于复杂状态逻辑。
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:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<div>
<p>计数: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</div>
);
}
自定义 Hooks[编辑 | 编辑源代码]
自定义 Hooks 是封装可复用逻辑的函数,命名需以 `use` 开头。
import { useState, useEffect } from 'react';
function useFetch(url) {
const [data, setData] = useState(null);
useEffect(() => {
fetch(url)
.then(response => response.json())
.then(data => setData(data));
}, [url]);
return data;
}
function UserProfile({ userId }) {
const user = useFetch(`/api/users/${userId}`);
return user ? <div>{user.name}</div> : <div>加载中...</div>;
}
实际案例[编辑 | 编辑源代码]
表单处理[编辑 | 编辑源代码]
使用 `useState` 管理表单输入:
function LoginForm() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
console.log({ email, password });
};
return (
<form onSubmit={handleSubmit}>
<input type="email" value={email} onChange={(e) => setEmail(e.target.value)} />
<input type="password" value={password} onChange={(e) => setPassword(e.target.value)} />
<button type="submit">登录</button>
</form>
);
}
性能优化[编辑 | 编辑源代码]
useMemo 和 useCallback[编辑 | 编辑源代码]
- `useMemo`:缓存计算结果。
- `useCallback`:缓存函数。
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
const memoizedCallback = useCallback(() => doSomething(a, b), [a, b]);
总结[编辑 | 编辑源代码]
React Hooks 提供了一种更简洁的方式来编写 React 组件,同时支持逻辑复用和更好的代码组织。以下是关键点:
- **`useState`**:管理组件状态。
- **`useEffect`**:处理副作用。
- **`useContext`**:共享全局数据。
- **`useReducer`**:复杂状态管理。
- **自定义 Hooks**:封装可复用逻辑。
通过合理使用 Hooks,可以显著提升 React 应用的开发效率和可维护性。