react hook useReducer的实践

简介: react16以来,无论是react实践多年的大佬,还是刚入门的萌新,都对hook有着很深的依赖,能快速使用hook特性来开发复杂功能的页面,减少类组件中繁琐的生命周期和复杂难懂的类语法,那么初用hook经常用到的无非useState,useEffect等基础hook,当遇到复杂逻辑,比如父组件带入参数,本身组件state参数很多,如果坚持使用state,将会有几十个state变量,如果维护起来,将非常耗时耗力,bug率很高,这里我们共同学习复习下state的替代方案,也是优化方案----useReducer

首先可以参考官方对useReducer的解释:https://react.docschina.org/docs/hooks-reference.html#usereducer


其实官网已经很详细了,下边就我的经验总结一下;


useReducer是什么

此hook是useState 的替代方案。与其说是替代,我更愿意用优化来形容,熟悉 Redux 的话,就已经知道它如何工作了。它接收一个形如 (state, action) => newState 的 reducer,并返回当前的 state 以及与其配套的 dispatch 方法,通过变更state的值来触发页面数据更新,下边看下简单的定义方法:

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 (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}

此定义为基本方法,可以看出,useReducer实际可以定义多个state,然后通过一个方法统一管理当前页面的state。

为什么使用useReducer

这个和什么时候使用可以放到一起来说,现在假如有个页面,有列表分页参数,有数十个搜索调价参数,有是个父页面传过来的联动参数,此时我们不仅需要维护分页参数,维护页面本身的搜索参数,还要维护父页面带过来的参数,更有甚者,需要变更父页面带过来的参数,通知父页面进行响应的操作。

在新的react版本中,已经对state进行优化,通个方法内如果有多个setState的操作,会统一变更后再更新页面数据,这比之前每次执行setState都要变更页面数据性能好得多,但维护起来甚是困难,这个相比做过复杂crud页面的大佬们都深有体会,所以此时使用useReducer来统一管理,初始化父页面带入的参数,本页面统一控制state的变更,也能更方便的初始化页面state。

惰性初始化

此操作可以将用于计算 state 的逻辑提取到 reducer 外部,这也为将来对重置 state 的 action 做处理提供了便利:

function init(initialCount) {  return {count: initialCount};}
function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    case 'reset':      return init(action.payload);    default:
      throw new Error();
  }
}
function Counter({initialCount}) {
  const [state, dispatch] = useReducer(reducer, initialCount, init);  return (
    <>
      Count: {state.count}
      <button
        onClick={() => dispatch({type: 'reset', payload: initialCount})}>        Reset
      </button>
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}


总结

useReducer作为hook里面state的替代方案,在需要的时候使用会提高页面执行效率,减少维护迭代开发时间,也能有效降低bug产生率,据阿里前端团队相关统计,页面使用useReducer比useState可以有效减少80%的bug,当然如果页面只有一两个state需要维护,此时可以根据个人习惯,快速使用useState来实现页面逻辑也是可以的。


相关文章
|
前端开发 JavaScript
深入理解并实践React Hooks —— useEffect与useState
深入理解并实践React Hooks —— useEffect与useState
314 1
|
3月前
|
前端开发 JavaScript 流计算
React 18 流式渲染:解锁极致性能优化实践
React 18 流式渲染:解锁极致性能优化实践
276 80
|
2月前
|
前端开发 JavaScript 编译器
React编程新手入门实践教程
本书深入解析React核心思想与设计哲学,涵盖组件化思维、虚拟DOM原理及JSX本质,探讨函数组件与类组件特性,详解状态管理、生命周期控制及事件处理机制,帮助开发者掌握高效构建用户界面的技巧。
82 1
|
4月前
|
JSON 前端开发 算法
掌握Multi-Agent实践(三):ReAct Agent集成Bing和Google搜索功能,采用推理与执行交替策略,增强处理复杂任务能力
掌握Multi-Agent实践(三):ReAct Agent集成Bing和Google搜索功能,采用推理与执行交替策略,增强处理复杂任务能力
289 23
|
11月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
775 2
|
前端开发
react中 useContext 和useReducer的使用
react中 useContext 和useReducer的使用
react中 useContext 和useReducer的使用
|
10月前
|
前端开发 JavaScript
手敲Webpack 5:React + TypeScript项目脚手架搭建实践
手敲Webpack 5:React + TypeScript项目脚手架搭建实践
|
10月前
|
前端开发 JavaScript 中间件
React中使用​​useReducer​​​高阶钩子来管理状态
通过本文的介绍,您可以在React中使用 `useReducer`高阶钩子来管理复杂的状态逻辑。`useReducer`不仅提供了清晰的状态管理方式,还可以通过与 `useContext`结合,实现全局状态管理。此外,通过自定义中间件,可以进一步扩展其功能。希望本文对您理解和应用 `useReducer`有所帮助。
154 0
|
移动开发 前端开发 JavaScript
使用React Native进行跨平台移动开发:技术探索与实践
【8月更文挑战第10天】React Native以其跨平台、高性能、易学习等优势,在移动开发领域取得了显著的成果。通过合理使用React Native,开发者可以更加高效地开发出高质量、低成本的移动应用。然而,在享受React Native带来的便利的同时,我们也需要关注其潜在的挑战和限制,并通过不断学习和实践来提升我们的开发能力。
|
前端开发 JavaScript UED
深入React Hooks与性能优化实践
深入React Hooks与性能优化实践
190 0