react的 useReducer 使用场景及替代 useState
useReducer 是 React 提供的状态管理 Hook,适合处理复杂状态逻辑。很多场景用 useState 能写,但随着状态增多、更新规则复杂,代码会变乱,这时候 useReducer 更适合。
一、useReducer 基础概念
语法:
const [state, dispatch] = useReducer(reducer, initialState);
参数:
- state:当前状态
- dispatch(action):触发更新
- reducer:状态处理函数
- initialState:初始值
类似 Redux:
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 (
<>
<p>{state.count}</p>
<button
onClick={() =>
dispatch({ type: 'increment' })
}
>
+
</button>
<button
onClick={() =>
dispatch({ type: 'decrement' })
}
>
-
</button>
</>
);
}二、什么时候useState不够用了?
场景1:多个相关状态一起维护(推荐 useReducer)
useState 写法
例如登录表单:
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [loading, setLoading] = useState(false);
const [error, setError] = useState('');提交:
setLoading(true);
api.login()
.then(() => {
setLoading(false);
})
.catch(() => {
setError('失败');
setLoading(false);
});状态多时:
username
password
loading
error
success
token
userInfo
会越来越乱。
useReducer:
const initialState = {
username: '',
password: '',
loading: false,
error: ''
};
function reducer(state, action) {
switch (action.type) {
case 'SET_USERNAME':
return {
...state,
username: action.payload
};
case 'LOGIN_START':
return {
...state,
loading: true
};
case 'LOGIN_FAIL':
return {
...state,
loading: false,
error: action.payload
};
default:
return state;
}
}
const [state, dispatch] =
useReducer(reducer, initialState);更新:
dispatch({
type: 'SET_USERNAME',
payload: '张三'
});逻辑集中。
适合:
✅ 表单
✅ 登录流程
✅ 搜索筛选条件
✅ 弹窗状态
场景2:状态之间有关联
例如购物车:
状态:
商品数量
总价
优惠金额
是否可提交
如果:
setCount() setPrice() setDiscount() setCanSubmit()
可能出现更新不同步。
用 reducer:
function reducer(state, action) {
switch(action.type){
case 'ADD_PRODUCT':
const count =
state.count + 1;
return {
count,
total:
count * state.price,
canSubmit:
count > 0
}
}
}一次更新全部状态。
适合:
购物车
订单
配置面板
步骤流
场景3:状态更新逻辑复杂
例如:
性能平台筛选条件:
云厂商
CPU架构
规格
产品代际
核数
自动联动
你之前做过类似:
选择 CPU → 自动填规格 → 自动填云厂商
多个接口联动:
选择规格
↓
请求接口
↓
更新5个状态
↓
重置表单
这类就适合 reducer:
dispatch({
type:'UPDATE_FILTER',
payload:data
})统一管理。
场景4:状态机(步骤流)
例如:
上传文件:
idle
uploading
success
error
useReducer:
function reducer(state, action) {
switch(action.type){
case 'UPLOAD':
return {
status:'loading'
}
case 'SUCCESS':
return {
status:'success'
}
case 'FAIL':
return {
status:'error'
}
}
}比:
loading
success
error
多个 bool 更清晰。
适合:
上传
支付
审批流
登录
任务执行
场景5:多人协作,希望逻辑统一
useState
更新散落:
setA() setB() setC()
难找。
useReducer
统一:
dispatch({
type:'UPDATE_USER'
})所有更新都进 reducer。
维护成本低。
三、什么时候不要用 useReducer?
简单状态:
const [visible, setVisible] const [count, setCount] const [name, setName]
没必要:
useReducer()
会增加复杂度。
建议:
| 状态复杂度 | 推荐 |
|---|---|
| 1~2 个简单状态 | useState |
| 多个相关状态 | useReducer |
| 状态联动 | useReducer |
| 复杂业务流程 | useReducer |
| 状态机 | useReducer |
| 大型组件 | useReducer |
| 全局状态 | useReducer + Context |
四、和 Redux 区别
很多人第一次看到:
dispatch() reducer() action.type
以为 Redux。
其实:
Redux:
全局状态
所有组件共享
useReducer:
组件内部状态
局部状态管理
组合使用:
Context + useReducer
≈ 简化版 Redux
适合中小项目。
可以记一句经验:
useState 管“值”,useReducer 管“状态变化规则”。
当你发现组件里出现很多:
setA() setB() setC() setD()
或者多个状态互相影响时,就可以考虑换 useReducer。这在你做性能平台那种“筛选条件联动 + 接口回填”的页面,会比多个 useState 更容易维护。
到此这篇关于react的 useReducer 使用场景及替代 useState的文章就介绍到这了,更多相关react useReducer 使用场景内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
react中使用better-scroll滚动插件的实现示例
滚动在很多地方都可以使用,本文主要介绍了react中使用better-scroll滚动插件的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2023-07-07
通过React-Native实现自定义横向滑动进度条的 ScrollView组件
开发一个首页摆放菜单入口的ScrollView可滑动组件,允许自定义横向滑动进度条,且内部渲染的菜单内容支持自定义展示的行数和列数,在内容超出屏幕后,渲染顺序为纵向由上至下依次排列,对React Native横向滑动进度条相关知识感兴趣的朋友一起看看吧2024-02-02
React关于antd table中select的设值更新问题
这篇文章主要介绍了React关于antd table中select的设值更新问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2024-03-03


最新评论