React Hooks完全指南:从基础到进阶
大家好,我是蔓蔓。React Hooks是React 16.8引入的一个革命性特性,它让我们能够在函数组件中使用状态和其他React特性。今天我来和大家分享React Hooks的完整用法。
基础Hooks
useState
javascript
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const [name, setName] = useState('蔓蔓');
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
<input
value={name}
onChange={(e) => setName(e.target.value)}
/>
</div>
);
}
useEffect
javascript
import { useState, useEffect } from 'react';
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchUser = async () => {
setLoading(true);
const response = await fetch(`/api/users/${userId}`);
const data = await response.json();
setUser(data);
setLoading(false);
};
fetchUser();
// 清理函数
return () => {
console.log('Cleanup');
};
}, [userId]); // 依赖数组
if (loading) return <div>Loading...</div>;
return <div>{user.name}</div>;
}
useContext
javascript
import { createContext, useContext } from 'react';
const ThemeContext = createContext('light');
function App() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {
const theme = useContext(ThemeContext);
return <div>Theme: {theme}</div>;
}
进阶Hooks
useReducer
javascript
import { 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 };
case 'reset':
return initialState;
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>
<button onClick={() => dispatch({ type: 'reset' })}>Reset</button>
</div>
);
}
useCallback和useMemo
javascript
import { useState, useCallback, useMemo } from 'react';
function expensiveCalculation(num) {
console.log('Calculating...');
return num * 2;
}
function App() {
const [count, setCount] = useState(0);
const [name, setName] = useState('');
// useMemo - 缓存计算结果
const doubled = useMemo(() => expensiveCalculation(count), [count]);
// useCallback - 缓存函数引用
const handleClick = useCallback(() => {
console.log('Clicked:', count);
}, [count]);
return (
<div>
<p>Count: {count}</p>
<p>Doubled: {doubled}</p>
<button onClick={() => setCount(c => c + 1)}>Increment</button>
<input
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Name"
/>
<button onClick={handleClick}>Log</button>
</div>
);
}
useRef
javascript
import { useRef, useEffect } from 'react';
function FocusInput() {
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus();
}, []);
return <input ref={inputRef} />;
}
// 存储可变值
function Timer() {
const intervalRef = useRef(null);
const [count, setCount] = useState(0);
useEffect(() => {
intervalRef.current = setInterval(() => {
setCount(c => c + 1);
}, 1000);
return () => {
clearInterval(intervalRef.current);
};
}, []);
return <div>Count: {count}</div>;
}
自定义Hooks
javascript
// useLocalStorage.js
import { useState, useEffect } from 'react';
export function useLocalStorage(key, initialValue) {
const [storedValue, setStoredValue] = useState(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.error(error);
return initialValue;
}
});
useEffect(() => {
try {
window.localStorage.setItem(key, JSON.stringify(storedValue));
} catch (error) {
console.error(error);
}
}, [key, storedValue]);
return [storedValue, setStoredValue];
}
// 使用
function App() {
const [name, setName] = useLocalStorage('name', '蔓蔓');
return (
<input
value={name}
onChange={(e) => setName(e.target.value)}
/>
);
}
Hooks规则
javascript
// ✅ 正确:在函数顶层调用
function GoodComponent() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log(count);
});
return <div>{count}</div>;
}
// ❌ 错误:在条件语句中调用
function BadComponent() {
if (someCondition) {
const [count, setCount] = useState(0); // ❌
}
return <div>Hello</div>;
}
// ✅ 正确:依赖数组包含所有依赖
function GoodEffect() {
const [count, setCount] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
console.log(count);
}, 1000);
return () => clearInterval(timer);
}, [count]);
return <div>{count}</div>;
}
总结
React Hooks让函数组件更强大:
- useState管理状态
- useEffect处理副作用
- useContext跨组件传递数据
- useReducer管理复杂状态
- useCallback和useMemo优化性能
- 自定义Hooks复用逻辑
技术应当有温度,好的Hooks使用能让代码更简洁优雅。