React复习全攻略:浅尝Redux的全局滋味

news2024/11/29 11:37:55

在这里插入图片描述

是什么?

Redux 是一个使用叫做 “action” 的事件来管理和更新应用状态的模式和工具库

  • 提供全局状态数据的单一仓库(对象树),管理应用的全局状态
  • 单一数据源,状态只读,状态修改只由纯函数完成

为什么用(特点)?

在这里插入图片描述

适用场景:

  • 多组件共用同一个 state 状态
  • 更新 state 的逻辑复杂度高
  • 多人协同开发,中型及以上的项目

常用的包:

Redux 常用涉及的包,主要是 ReduxRedux-ToolkitReact-ReduxRedux-Thunk,以及调试工具 Redux-Devtools-Extension

  • Redux:Redux 的核心包。它提供了创建 store、统一管理 reducer、绑定 action、中间件集成及管理等组件。
  • Redux-Toolkit:Redux 的工具包。提供一系列简单易用的 API 和工具,简化 Redux 的开发和代码质量。
  • React-Redux:是 Redux 的官方 React 绑定库。其目的是让 React 组件能够使用 Redux 状态管理。
  • Redux-Thunk中间件,用于处理异步操作。使 dispatch 可以接受函数,赋予其执行异步操作的能力。
  • Redux-Devtools-Extension:Redux 的调试工具。可以显示 Redux 存储中状态随时间变化的历史记录

三大核心概念

  • Action: 动作对象,包含两个属性。是改变 state 的唯一方法
    • type:必填,唯一性,String 类型,标识属性
    • data:可选,放数据用的。
    • 举例:{ type: 'TOGGLE_TODO', index: 1 }
  • Reducer:用于初始化状态、加工状态的纯函数。加工时,根据当前的 state 和 action,产生新的 state。
  • Store: 将 state、action、reducer 联系在一起的对象。可以将Store理解为全局的一个变量,且全局只有一个Store。

怎么用?

在 React 项目里面使用 Redux,必不可少要先安装 ReduxReact-Redux

npm install redux 
npm install react-redux

Redux 基本使用

使用 Redux 的核心 createStore 进行状态管理,这是最基本的方法。

现已被官方标记弃用,原因是Redux 4.2以后鼓励用户用户使用 Redux-Toolkit

但这并不影响我们对于它的了解,以及如何使用。

我们来举个例子,加减数字的功能

1. 首先,我们先建立一个 counter 的 reducer

// src/reducer/counter.js
const initialState = {
  count: 0,
};

export default function counterReducer(state = initialState, action) {
  switch (action.type) {
    case 'INCREMENT':
      return {
        ...state,
        count: state.count + 1,
      };
    case 'DECREMENT':
      return {
        ...state,
        count: state.count - 1,
      };
    default:
      return state;
  }
}

2. 可创建多个 reducer,通过 combineReducers 方法集成一个 rootReducer

// src/reducer/index.js
import { combineReducers } from 'redux';
import counterReducer from './counter';

export default combineReducers({
  counter: counterReducer,
  // ... 其他 reducer  
});  

3. 导入 rootReducer,再由 createStore 创建 store

// src/store/index.js
import { createStore } from 'redux';
import rootReducer from '../reducer';

const store = createStore(rootReducer)

export default store;

4. 最后在应用中集成 Redux Store

// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import App from './App';
import store from './store';

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

5. 组件里使用

在上述,状态仓库通过 createStore,已经创建完毕。创建完了,我们就该去使用这个 store 了。

在这一小节,我们将通过 React-Redux ,useSelector 取值,useDispatch 发出动作去修改值,从而实现这个加减功能。

// src/App.jsx
import { useSelector, useDispatch } from 'react-redux';

function App() {
  const { count } = useSelector((state) => state.counter)
  const dispatch = useDispatch();

  return (
    <div className="App">
      <p>Count: { count }</p>
      <button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment</button>
      <button onClick={() => dispatch({ type: 'DECREMENT' })}>Decrement</button>
    </div>
  );
}

export default App;

有没有觉得用一个全局状态变量,就得这么多步骤,太恶心了吧

这正是官方后续出了 Redux-Toolkit 的原因,那下面我们就用它

Redux-Toolkit 使用

首先,你需要安装它:

npm install @reduxjs/toolkit

1. createSlice 创建 reducer

还是一样,我们先创建一个名为 countreducer

// src/reducer/count.js
import { createSlice } from '@reduxjs/toolkit';

const initialState = {
  count: 0,
};

const counterSlice = createSlice({
  name: "counter",
  initialState,
  reducers: {
    increment(state) {
      state.count++;
    },
    decrement(state) {
      state.count--;
    }
  }
})

export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;

2. configureStore 创建 store

configureStore 有添加更多 reducer 的功能并创建 store,直接省去了合并 rootReducer 的步骤

// src/store/index.js
import { configureStore } from '@reduxjs/toolkit';  
import counterReducer from '../slice/counter';  
  
const store = configureStore({  
  reducer: {  
    counter: counterReducer,  
    // 可以添加更多的 reducer  
  },  
});  
  

export default store;

3. 应用中集成 Redux Store

和上一种方法一样,使用 React-Redux 的 Provider 组件,让组件能够有状态管理

// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import App from './App';
import store from './store';

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

4. 组件里使用

组件里使用,和上一种方法也大差不差,主要是加了 action 的导入

// src/App.jsx
import { useSelector, useDispatch } from 'react-redux';
// 就加了这里
import { increment, decrement } from './reducer/counter'; 

function App() {
  const { count } = useSelector((state) => state.counter)
  const dispatch = useDispatch();

  return (
    <div className="App">
      <p>Count: {count}</p>
      <button onClick={() => dispatch(increment())}>Increment</button>
      <button onClick={() => dispatch(decrement())}>Decrement</button>
    </div>
  );
}

export default App;

Redux DevTools 调试

我们在上述编写完加减数字的功能后,可以下载 Redux DevTools 进行直观的展示,以加深对 Redux 的理解。

扩展插件,可通过网上应用商店获取,非常方便:
在这里插入图片描述

添加完毕后,在 React 页面中,F12 呼出开发调试工具,选 Redux 标签就能看到以下数据:
在这里插入图片描述

Redux-Thunk 使用

Redux-Thunk 是一个用于处理 Redux 中异步操作的中间件

在 Redux 中,reducers 应该是纯函数,只负责处理同步的状态变更,而 Redux-Thunk 则允许你派发一个返回函数的 action,这个函数可以执行异步操作,比如发起 API 请求,然后在异步操作完成后,再派发一个真正的 action 来更新 Redux 中的状态。

其作用

  • 处理异步操作:通过派发返回函数的 action,你可以执行诸如 API 请求等异步任务,并在任务完成后更新应用状态。
  • 控制流:Redux-Thunk 允许你在派发 action 时进行条件判断、流程控制等操作,从而更灵活地处理不同情况下的异步行为。

下面是一个简单的 Redux-Thunk 使用示例:

import { createStore, applyMiddleware } from 'redux';  
import thunk from 'redux-thunk';  
import rootReducer from './reducers';  
  
// 创建一个Redux store,并应用redux-thunk中间件  
const store = createStore(rootReducer, applyMiddleware(thunk));  
  
// 一个异步action创建函数  
function fetchPostsRequest() {  
  return {  
    type: 'FETCH_POSTS_REQUEST'  
  };  
}  
  
function fetchPostsSuccess(posts) {  
  return {  
    type: 'FETCH_POSTS_SUCCESS',  
    payload: posts  
  };  
}  
  
function fetchPostsError(error) {  
  return {  
    type: 'FETCH_POSTS_ERROR',  
    payload: error  
  };  
}  
  
// 使用redux-thunk,我们可以派发一个返回函数的action  
export function fetchPosts() {  
  return function(dispatch) {  
    dispatch(fetchPostsRequest());  
  
    return fetch('https://api.example.com/posts')  
      .then(response => response.json())  
      .then(posts => dispatch(fetchPostsSuccess(posts)))  
      .catch(error => dispatch(fetchPostsError(error)));  
  };  
}

在这个示例中,fetchPosts是一个异步 action 创建函数,它返回一个函数。这个函数首先派发一个FETCH_POSTS_REQUEST action 来指示开始获取帖子,然后发起一个 API 请求。当请求成功时,它派发一个FETCH_POSTS_SUCCESS action 并带上获取到的帖子数据;如果请求失败,则派发一个FETCH_POSTS_ERROR action 并带上错误信息。

通过这种方式,你可以将异步逻辑与 Redux 的状态管理结合起来,实现更加健壮和可维护的应用。


结束语

在 React 的复习全攻略中,Redux 无疑是一个不可忽视的篇章。

浅尝 Redux 的全局滋味,我们不仅能领略到其集中式状态管理的魅力,更能感受到它如何助力 React 应用实现数据流的清晰可控

Redux 的出现,极大地简化了组件间的通信,让我们的代码更加整洁高效

掌握 Redux,不仅意味着我们能够更好地驾驭 React 应用的全局状态,更是提升我们开发能力的重要一步。

无论是初学者还是资深开发者,Redux 都是值得我们去深入学习和探索的领域~。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1586625.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言操作符详解(三)

一、表达式求值 1.1整型提升 C语言中整型算术运算总是至少以缺省整型类型的精度来进行的。 为了获得这个精度&#xff0c;表达式中的字符和短整型操作数在使用之前被转换为普通整型&#xff0c;这种转换称为整型提升。 如何进行整型提升呢&#xff1f; 1. 有符号整数提升是按…

如何理解Fourier Neural Operator (FNO)

写这篇blog是因为多方参考才读懂这两篇文章&#xff0c;希望能用自己的语言表达出来加深一下理解。因为是刚刚开始学习这部分内容&#xff0c;错误之处敬请指出。 文章目录 前言算子Operator概念理解问题建立Graph Neural Operator的思想证明采样多少个数据点可以用来表示一组a…

五金件外观检测机如何确保产品质量?

五金件是指由金属材料制成的各种零部件或制品&#xff0c;主要用于各种机械设备、工具、建筑结构以及其他领域。五金件通常由金属加工、铸造、锻造等方式制造&#xff0c;具有耐久性、强度高、稳定性强等特点。应用于工业制造、建筑、家具、汽车、电子产品等领域。 本案五金件尺…

Linux使用C语言实现Socket编程

Socket编程 这一个课程的笔记 相关文章 协议 Socket编程 高并发服务器实现 线程池 网络套接字 socket: &#xff08;电源&#xff09;插座&#xff08;电器上的&#xff09;插口&#xff0c;插孔&#xff0c;管座 在通信过程中, 套接字是成对存在的, 一个客户端的套接字, 一个…

佛山市人工智能产业生态交流会:实在智能Agent引领“智造浪潮”

制造业&#xff0c;实体经济的核心&#xff0c;技术创新的先锋&#xff0c;供给侧结构性改革的关键。在新一轮产业竞争中&#xff0c;数字化转型成为制造业升级的必由之路&#xff0c;是引领未来的重要抓手。 为促进数字经济赋能实体经济&#xff0c;加快人工智能技术的推广应用…

Object类里面的clone方法与接口cloneable的理解

文章目录 前言一、Object类二、Cloneable接口 前言 今天在进行使用clone方法时产生了一个疑问&#xff0c;为什么Object类明明有clone()方法&#xff0c;但为什么还要加上cloneable这个接口呢&#xff0c;下面我们就来解答一下为什么要重写clone()方法非要加上cloneable接口&a…

Ant Design 表单基础用法综合示例

Ant Design 的表单组件设计得非常出色,极大地简化了表单开发的复杂度,让开发者能够快速构建出功能丰富、交互友好的表单界面。 接下来总结一下 Ant Design 中表单的基本用法。 Form 组件 用于定义整个表单,可以设置表单的布局方式、提交行为等。通常会将表单字段组件嵌套在 F…

Meta宣布全新训推一体加速器:完全集成PyTorch 2,性能3倍提升

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站https://ai.hzytsoft.cn/ 更多资源欢迎关注 Meta 疯狂砸入数十亿美元&#xff0c;一部分招揽人才&#xff0c;一部分造芯片。 Meta 正在不…

用户状态保持机制-Session

0、业务需求 会话&#xff1a;web应用中的会话是指一个客户端浏览器和服务器之间连续发生的一系列请求和响应的过程。 会话状态&#xff1a;web应用中的会话状态是指web服务器与浏览器在会话过程中产生的状态信息&#xff0c;借助会话状态&#xff0c;服务器能够把属于同一会话…

1572. 【基础赛】涂色(paint)

1572. 【基础赛】涂色&#xff08;paint&#xff09; (Input: paint.in, Output: paint.out) 时间限制: 2 s 空间限制: 256 MB 具体限制 题目描述 Introl获得了一个N行的杨辉三角&#xff0c;他将每行中值为奇数的位置涂为了黑色。 Chihiro将提出M次询问&#xff0c;在第L…

51单片机上面的IIC协议

1、什么是IIC协议 2、模拟IIC协议 51单片机上面是没有与IIC协议相关的寄存器的&#xff08;没有相关的硬件&#xff09;&#xff0c;不像串口可以配置对应的寄存器达到目的&#xff08;比如修改波特率9600 or 115200&#xff09;&#xff0c;要配置IIC只能够根据用户手册里面的…

【LeetCode】单调栈类题目详解

所有题目均来自于LeetCode&#xff0c;刷题代码使用的Python3版本 单调栈 通常针对一维数组的问题&#xff0c;如果需要寻找一个元素右边或者左边第一个比自己大或者小的元素的位置&#xff0c;就可以使用单调栈&#xff0c;时间复杂度为O(n) 单调栈的本质是空间换时间&#…

[AIGC] Spring中的SPI机制详解

文章目录 1. 什么是SPI2. Spring中的SPI机制3. Spring SPI的工作流程4. Spring SPI的应用 1. 什么是SPI SPI &#xff08;Service Provider Interface&#xff09;是Java中服务提供者接口的缩写&#xff0c;它是Java提供的一种用于被第三方实现或扩展的接口&#xff0c;SPI的作…

2024 年最新前端工程师使用 Webpack 模块打包工具详细教程(更新中)

概述 Webpack 模块打包工具 Webpack 是一个现代的静态模块打包工具&#xff0c;用于将前端应用程序的各种资源&#xff08;例如如&#xff1a;JavaScript、CSS、图片等&#xff09;视为模块&#xff0c;并将它们打包成可以在浏览器中运行的静态文件。它的主要功能包括模块打包…

对 FileReader 的理解

1、文档 FileReader - Web API 接口参考 | MDN 2、概念 FileReader 对象是一个内置的 JavaScript 对象&#xff0c;用于在客户端&#xff08;浏览器&#xff09;中异步读取文件内容。 它提供了一种在 Web 应用程序中读取文件数据的方式&#xff0c;可以读取文件内容并将其转…

跟TED演讲学英文:The next grand challenge for AI by Jim Fan

The next grand challenge for AI Link: https://www.ted.com/talks/jim_fan_the_next_grand_challenge_for_ai? Speaker: Jim Fan Date: October 2023 文章目录 The next grand challenge for AIIntroductionVocabularyTranscriptSummary后记 Introduction Researcher Jim…

MySQL事务、主从、分库分表常见面试题

文章目录 1.事务的特性2.并发事务问题&#xff0c;如何解决&#xff0c;默认隔离级别3.undo log和redo log的区别4.事务中的隔离性是如何保证的&#xff08;解释一下MVCC&#xff09;5.主从同步原理6.分库分表 1.事务的特性 2.并发事务问题&#xff0c;如何解决&#xff0c;默认…

2022年蓝桥杯省赛软件类C/C++B组----积木画

想借着这一个题回顾一下动态规划问题的基本解法&#xff0c;让解题方法清晰有条理&#xff0c;希望更多的人可以更轻松的理解动态规划&#xff01; 目录 【题目】 【本题解题思路】 【DP模版】 总体方针&#xff1a; 具体解题时的套路&#xff1a; 【题目】 【本题解题思…

压缩列表ziplist

目录 1压缩列表的结构 2.压缩列表节点的构成 previous_entry_length encodeing conent 3.压缩列表API 1.创建列表 ziplistNew 2.正向遍历 ziplistNext 3.反向遍历 ziplistPrev 4.插入元素 ziplistInsert 5.级联更新 __ziplistCascadeUpdate 6.删除节点 7.查找entr…

L2-2 巴音布鲁克永远的土(二分+并查集)

思路&#xff1a;我们可以二分答案&#xff0c;然后判断当前答案合不合理。 对于判断答案合理&#xff0c;可以用并查集&#xff0c;看mid能否把所有检查点连进一个集合中&#xff0c;枚举每个结点&#xff0c;如何当前结点周围的四个方向可以连的话&#xff0c;就加进同一个集…