React Hooks 是 React 16.8 引入的重要特性,它允许开发者在函数组件中使用状态和其他 React 特性。本文将详细介绍 6 个最常用的 React Hooks。
1. useState
useState 是最常用的 Hook,用于在函数组件中添加 state。
javascript
import React, { useState } from 'react';
function Counter() {
// 声明一个叫做 "count" 的 state 变量,初始值为 0
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
useState 返回一个数组,第一个元素是当前状态值,第二个元素是更新状态的函数。
2. useEffect
useEffect 用于在函数组件中执行副作用操作,例如数据获取、订阅或手动更改 DOM。
javascript
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// 类似于 componentDidMount 和 componentDidUpdate
useEffect(() => {
// 使用浏览器 API 更新文档标题
document.title = `You clicked ${count} times`;
// 清除副作用
return () => {
document.title = 'React App';
};
}, [count]); // 仅在 count 更改时重新运行
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
useEffect 接受两个参数:一个包含副作用逻辑的函数和一个依赖数组。
3. useContext
useContext 接受一个 context 对象(React.createContext 的返回值)并返回该 context 的当前值。
javascript
import React, { useContext } from 'react';
const ThemeContext = React.createContext('light');
function ThemeButton() {
const theme = useContext(ThemeContext);
return <button style={{ background: theme }}>Theme Button</button>;
}
function App() {
return (
<ThemeContext.Provider value="dark">
<ThemeButton />
</ThemeContext.Provider>
);
}
useContext 使得在函数组件中访问上下文变得非常简单。
4. useReducer
useReducer 是 useState 的替代方案,适用于 state 逻辑较复杂且包含多个子值,或下一个 state 依赖于之前的 state 的情况。
javascript
import React, { useReducer } from 'react';
const initialState = { count: 0 };
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, initialState);
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</div>
);
}
useReducer 特别适合管理复杂的状态逻辑。
5. useRef
useRef 返回一个可变的 ref 对象,该对象的 .current 属性被初始化为传入的参数。常用于访问 DOM 元素或存储可变值。
javascript
import React, { useRef } from 'react';
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
// 使用原生 DOM API 聚焦文本输入
inputEl.current.focus();
};
return (
<div>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</div>
);
}
useRef 的值在组件重新渲染时保持不变。
6. useMemo 和 useCallback
这两个 Hook 都用于性能优化。
6.1. useMemo 用法
javascript
import React, { useMemo } from 'react';
function ExpensiveCalculationComponent({ number }) {
const compute = (n) => {
console.log('Expensive computation');
return n * 2;
};
const result = useMemo(() => compute(number), [number]);
return <div>Result: {result}</div>;
}
6.2. useCallback 用法
javascript
import React, { useState, useCallback } from 'react';
function Button({ onClick, children }) {
return <button onClick={onClick}>{children}</button>;
}
function App() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
setCount(count + 1);
}, [count]);
return (
<div>
<p>Count: {count}</p>
<Button onClick={handleClick}>Increment</Button>
</div>
);
}
useMemo 用于记忆化计算结果,useCallback 用于记忆化函数,两者都只在依赖项变化时重新计算。
7. 总结
React Hooks 提供了一种更简洁、更直观的方式来使用 React 的特性。从简单的状态管理到复杂的副作用处理,Hooks 都能提供优雅的解决方案。掌握这些基础 Hook 是成为高效 React 开发者的关键一步。