1. 基本用法
1.1 声明状态
javascript
复制代码
import React, { useState } from 'react';
function Example() {
// 声明一个叫 count 的 state,初始值为 0
const [count, setCount] = useState(0);
return (
<div>
<p>当前计数: {count}</p>
<button onClick={() => setCount(count + 1)}>
增加
</button>
</div>
);
}
1.2 多个状态声明
javascript
复制代码
function UserForm() {
const [name, setName] = useState('');
const [age, setAge] = useState(0);
const [email, setEmail] = useState('');
return (
<form>
<input
value={name}
onChange={e => setName(e.target.value)}
placeholder="姓名"
/>
<input
type="number"
value={age}
onChange={e => setAge(Number(e.target.value))}
placeholder="年龄"
/>
<input
value={email}
onChange={e => setEmail(e.target.value)}
placeholder="邮箱"
/>
</form>
);
}
2. 状态更新
2.1 基础更新
javascript
复制代码
function Counter() {
const [count, setCount] = useState(0);
// 直接设置新值
const increment = () => setCount(count + 1);
// 使用函数式更新
const decrement = () => setCount(prevCount => prevCount - 1);
return (
<div>
<button onClick={decrement}>-</button>
<span>{count}</span>
<button onClick={increment}>+</button>
</div>
);
}
2.2 对象状态更新
javascript
复制代码
function UserProfile() {
const [user, setUser] = useState({
name: '',
age: 0,
email: ''
});
// 更新对象的某个属性
const updateName = (name) => {
setUser(prevUser => ({
...prevUser,
name
}));
};
// 批量更新多个属性
const updateProfile = (updates) => {
setUser(prevUser => ({
...prevUser,
...updates
}));
};
return (
<div>
<input
value={user.name}
onChange={e => updateName(e.target.value)}
/>
<button onClick={() => updateProfile({ age: 25, email: 'test@example.com' })}>
更新信息
</button>
</div>
);
}
2.3 数组状态更新
javascript
复制代码
function TodoList() {
const [todos, setTodos] = useState([]);
// 添加项
const addTodo = (text) => {
setTodos(prevTodos => [
...prevTodos,
{ id: Date.now(), text, completed: false }
]);
};
// 删除项
const removeTodo = (id) => {
setTodos(prevTodos => prevTodos.filter(todo => todo.id !== id));
};
// 更新项
const toggleTodo = (id) => {
setTodos(prevTodos => prevTodos.map(todo =>
todo.id === id
? { ...todo, completed: !todo.completed }
: todo
));
};
return (
<div>
<button onClick={() => addTodo('新任务')}>添加任务</button>
<ul>
{todos.map(todo => (
<li key={todo.id}>
<input
type="checkbox"
checked={todo.completed}
onChange={() => toggleTodo(todo.id)}
/>
<span>{todo.text}</span>
<button onClick={() => removeTodo(todo.id)}>删除</button>
</li>
))}
</ul>
</div>
);
}
3. 高级用法
3.1 惰性初始化
javascript
复制代码
function ExpensiveComponent() {
// 惰性初始化:初始值通过函数计算
const [state, setState] = useState(() => {
const initialValue = expensiveComputation();
return initialValue;
});
return <div>{state}</div>;
}
3.2 状态重置
javascript
复制代码
function ResetableCounter() {
const [count, setCount] = useState(0);
// 重置状态到初始值
const reset = () => setCount(0);
return (
<div>
Count: {count}
<button onClick={() => setCount(count + 1)}>增加</button>
<button onClick={reset}>重置</button>
</div>
);
}
3.3 派生状态
javascript
复制代码
function DerivedStateExample() {
const [list, setList] = useState([1, 2, 3, 4, 5]);
// 派生状态:基于现有状态计算
const evenNumbers = list.filter(n => n % 2 === 0);
const total = list.reduce((sum, n) => sum + n, 0);
return (
<div>
<p>所有数字: {list.join(', ')}</p>
<p>偶数: {evenNumbers.join(', ')}</p>
<p>总和: {total}</p>
</div>
);
}
4. 常见使用场景
4.1 表单处理
javascript
复制代码
function Form() {
const [formData, setFormData] = useState({
username: '',
password: '',
email: ''
});
const handleChange = (e) => {
const { name, value } = e.target;
setFormData(prev => ({
...prev,
[name]: value
}));
};
const handleSubmit = (e) => {
e.preventDefault();
console.log('提交表单:', formData);
};
return (
<form onSubmit={handleSubmit}>
<input
name="username"
value={formData.username}
onChange={handleChange}
/>
<input
name="password"
type="password"
value={formData.password}
onChange={handleChange}
/>
<input
name="email"
type="email"
value={formData.email}
onChange={handleChange}
/>
<button type="submit">提交</button>
</form>
);
}
4.2 异步数据加载
javascript
复制代码
function DataFetcher() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const fetchData = async () => {
setLoading(true);
try {
const response = await fetch('https://api.example.com/data');
const result = await response.json();
setData(result);
setError(null);
} catch (err) {
setError(err.message);
setData(null);
} finally {
setLoading(false);
}
};
return (
<div>
<button onClick={fetchData}>加载数据</button>
{loading && <p>加载中...</p>}
{error && <p>错误: {error}</p>}
{data && <pre>{JSON.stringify(data, null, 2)}</pre>}
</div>
);
}
5. 性能优化
5.1 避免不必要的更新
javascript
复制代码
function OptimizedComponent() {
const [count, setCount] = useState(0);
// 使用回调函数避免重复创建函数
const increment = useCallback(() => {
setCount(c => c + 1);
}, []);
return <button onClick={increment}>Count: {count}</button>;
}
5.2 状态分割
javascript
复制代码
// 不好的做法:将不相关的状态放在一起
function BadExample() {
const [state, setState] = useState({
count: 0,
user: null,
theme: 'light'
});
}
// 好的做法:将状态分开管理
function GoodExample() {
const [count, setCount] = useState(0);
const [user, setUser] = useState(null);
const [theme, setTheme] = useState('light');
}
6. 最佳实践
6.1 状态设计原则
- 保持状态最小化
- 避免冗余状态
- 避免状态耦合
- 使用合适的数据结构
6.2 使用建议
- 合理命名状态和更新函数
- 使用函数式更新处理依赖之前的状态
- 适当拆分组件和状态
- 注意状态更新的性能影响
7. 总结
7.1 核心要点
- useState 用于在函数组件中管理状态
- 状态更新是异步的
- 使用函数式更新处理依赖之前的状态
- 合理组织和拆分状态
7.2 注意事项
- 不要在循环、条件或嵌套函数中使用 useState
- 确保状态更新的不可变性
- 避免过度使用状态
- 正确处理复杂状态的更新