当前位置: 首页 > news >正文

什么是redux?如何在react 项目中使用redux?

redux 概念

redux是一种用于管理JavaScript应用程序的状态管理库。它可以与React、Augular、Vue等前端框架结合使用,但也可以纯在JavaScript应用程序中独立使用。redux遵循单项数据流的原则,通过一个全局的状态树来管理应用程序的状态,从而使状态的变化更加可预测和已于维护。
redux的核心概念包括:

  1. Store: redux 的状态储存仓库,包括整个应用程序的状态树。应用程序中的所有状态都保存在整个单一的状态树中。
  2. Action: 代表状态变化的对象。它是一个包含type字段的JavaScript对象,用于描述发生的事件类型,并可以携带一些额外的数据。
  3. Reducer:纯函数,用于处理状态变化。接受旧的状态和一个action作为参数,返回一个新的状态。
  4. Dispatch:将action发送到reducer的过程,通过调用store.dispatch(action)来触发状态的变化。
  5. Subscribe:用于注册监听器,当状态发送变化时,可以通过store.subcribe(listener)来执行回调函数。
    下面时一个简单的redux示例代码:
// 引入Redux
const { createStore } = require('redux');// 定义初始状态和Reducer
const initialState = { count: 0 };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;}
}// 创建Redux store
const store = createStore(counterReducer);// 订阅状态变化
store.subscribe(() => {const currentState = store.getState();console.log('Current state:', currentState);
});// 触发状态变化
store.dispatch({ type: 'INCREMENT' }); // 输出:Current state: { count: 1 }
store.dispatch({ type: 'INCREMENT' }); // 输出:Current state: { count: 2 }
store.dispatch({ type: 'DECREMENT' }); // 输出:Current state: { count: 1 }

如何在项目中封装一个全局状态。

在使用create-react-app创建的React项目中,可以使用reduxreact-redux来封装和管理全局状态。以下是在create-react-app项目中封装Redux并在需要的页面引入的步骤:

  1. 安装reduxreact-redux库:
npm install redux react-redux
  1. 创建Redux store:
    在项目的src目录下创建一个名为store的文件夹,并在该文件夹下创建一个index.js文件,用于创建Redux store。
// src/store/index.js
import { createStore } from 'redux';
import rootReducer from './reducers'; // 导入根Reducerconst store = createStore(rootReducer);export default store;

在上述代码中,使用createStore函数创建了Redux store,并传入了根ReducerrootReducer

  1. 创建Reducers:
    src/store文件夹下创建一个名为reducers.js的文件,用于定义和组合所有的Reducers。
// src/store/reducers.js
import { combineReducers } from 'redux';
// 导入其他Reducers,比如:
// import counterReducer from './counterReducer';const rootReducer = combineReducers({// 在这里将所有的Reducers组合起来// counter: counterReducer,
});export default rootReducer;

在这里,可以导入并组合所有的Reducers,如果你有多个Reducer,可以在这里添加并在combineReducers函数中进行组合。

  1. 创建Actions:
    src/store文件夹下创建一个名为actions.js的文件,用于定义Redux的Actions。
// src/store/actions.js
// 定义Action Types
export const INCREMENT = 'INCREMENT';
export const DECREMENT = 'DECREMENT';// 定义Action Creators
export const increment = () => ({ type: INCREMENT });
export const decrement = () => ({ type: DECREMENT });

在上述代码中,定义了两个Action Types和对应的Action Creators。

  1. 创建Reducer:
    src/store文件夹下创建一个名为counterReducer.js的文件,用于定义一个Reducer示例。
// src/store/counterReducer.js
import { INCREMENT, DECREMENT } from './actions';const initialState = { count: 0 };const 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;}
};export default counterReducer;

在上述代码中,定义了一个简单的counterReducer,根据不同的Action Type来处理状态的变化。

  1. 在需要的页面引入Redux:
    在你需要使用Redux的组件或页面中,可以使用react-redux提供的Provider组件将Redux store注入到应用中,使其在组件层次结构中的任何地方都可以访问全局状态。
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';ReactDOM.render(<Provider store={store}><App /></Provider>,document.getElementById('root')
);

在上述代码中,使用Provider组件将store作为prop传递给应用的根组件App

  1. 在组件中使用Redux的状态:
    现在你可以在需要的组件中使用Redux的状态了。通过react-redux提供的useSelectoruseDispatch等hooks,或者使用connect函数,你可以在组件中访问和修改全局状态。
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from './store/actions';const Counter = () => {const count = useSelector((state) => state.counter.count);const dispatch = useDispatch();return (<div><h1>Counter: {count}</h1><button onClick={() => dispatch(increment())}>Increment</button><button onClick={() => dispatch(decrement())}>Decrement</button></div>);
};export default Counter;

在上述代码中,使用useSelector获取counter的状态,以及使用useDispatch获取dispatch函数,从而在组件中对状态进行修改。

connect函数

react-redux中,connect函数是一个高阶函数(Higher-Order Function),它允许你将Redux的状态和dispatch函数作为props传递给React组件。使用connect函数可以将组件与Redux store连接起来,从而让组件可以访问和修改全局状态。

在React中,有两种方式可以访问和使用Redux的状态:

  1. 使用Hooks(推荐):react-redux提供了一些Hooks,如useSelectoruseDispatch。使用Hooks的方式更加简洁,直接,而且是React的新特性。可以在函数式组件中使用这些Hooks来获取Redux的状态和dispatch函数,例如:
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from './store/actions';const Counter = () => {const count = useSelector((state) => state.counter.count);const dispatch = useDispatch();return (<div><h1>Counter: {count}</h1><button onClick={() => dispatch(increment())}>Increment</button><button onClick={() => dispatch(decrement())}>Decrement</button></div>);
};export default Counter;
  1. 使用connect函数(旧版方式):在较早版本的react-redux中,Hooks可能不可用或者不适用于类组件,此时可以使用connect函数来实现连接。connect函数可以将Redux的状态和dispatch函数映射到组件的props上,这样组件就能够通过props来访问和修改Redux的状态。
import React from 'react';
import { connect } from 'react-redux';
import { increment, decrement } from './store/actions';class Counter extends React.Component {render() {const { count, increment, decrement } = this.props;return (<div><h1>Counter: {count}</h1><button onClick={increment}>Increment</button><button onClick={decrement}>Decrement</button></div>);}
}const mapStateToProps = (state) => {return {count: state.counter.count};
};const mapDispatchToProps = (dispatch) => {return {increment: () => dispatch(increment()),decrement: () => dispatch(decrement())};
};export default connect(mapStateToProps, mapDispatchToProps)(Counter);

在上述代码中,使用connect函数将Redux的状态映射到组件的props中,并定义了mapStateToPropsmapDispatchToProps函数来进行映射。

总结:
使用connect函数是较早版本react-redux的一种实现方式,而使用Hooks的方式则是React的新特性,更加简洁和方便。如果你使用的react-redux版本较新,并且项目支持React Hooks,那么推荐使用Hooks的方式来访问和修改Redux的状态。如果项目需要兼容旧版本的react-redux或需要在类组件中使用,那么可以考虑使用connect函数的方式。

相关文章:

什么是redux?如何在react 项目中使用redux?

redux 概念 redux是一种用于管理JavaScript应用程序的状态管理库。它可以与React、Augular、Vue等前端框架结合使用&#xff0c;但也可以纯在JavaScript应用程序中独立使用。redux遵循单项数据流的原则&#xff0c;通过一个全局的状态树来管理应用程序的状态&#xff0c;从而使…...

mysql的json处理

写在前面 需要注意&#xff0c;5.7以上版本才支持&#xff0c;但如果是生产环境需要使用的话&#xff0c;尽量使用8.0版本&#xff0c;因为8.0版本对json处理做了比较大的性能优化。你你可以使用select version();来查看版本信息。 本文看下MySQL的json处理。在正式开始让我们先…...

前端学习——Vue (Day8)

Vue3 create-vue搭建Vue3项目 注意要使用nodejs16.0版本以上&#xff0c;windows升级node可以西安使用where node查看本地node位置&#xff0c;然后到官网下载msi文件&#xff0c;在本地路径下安装即可 安装完可以使用node -v检查版本信息 项目目录和关键文件 组合式API - s…...

Windows环境下安装及部署Nginx

一、安装Nginx教程 1、官网下载地址&#xff1a;https://nginx.org/en/download.html 2、下载教程&#xff1a;选择Stable version版本下载到本地 3、下载完成后&#xff0c;解压放入本地非中文的文件夹中&#xff1a; 4、启动nginx&#xff1a;双击nginx.exe&#xff0c;若双击…...

使用AOP切面对返回的数据进行脱敏的问题

1.注解类 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/*** Author: xiaoxin* Date: 2023/7/21 17:15*/ Retention(RetentionPolicy.RUNTIME) Targe…...

TDengine时区设置

一般来说&#xff0c;时序数据就是带有时间序列属性的数据。在处理时序数据时&#xff0c;TDengine有着自己独特的方式。但是如果没有正确理解TDengine在写入和查询上的行为&#xff0c;极可能会因为配置了错误的时区&#xff08;timezone&#xff09;&#xff0c;而导致写入和…...

站外引流效果差?一文带你搞懂解海外主流社交媒体算法!

在流量成本越来越高的当下&#xff0c;无论是平台卖家还是独立站卖家都在努力拓展流量渠道。站外引流是推动业务增长的关键策略&#xff0c;很多卖家会把重点放在内容营销上&#xff0c;但其实除了做好内容之前&#xff0c;了解社交媒体的算法才能让营销效果最大化。 01.Faceb…...

css 动画之旋转视差

序&#xff1a;网上看到的一个例子&#xff0c;做一下 效果图&#xff1a; 代码&#xff1a; <style>.content{width: 300px;height: 300px;margin: 139px auto;display: grid;grid-template-columns: repeat(3,1fr);grid-template-rows: repeat(3,1fr);grid-template:…...

maven项目、springboot项目复制文件进来后没反应、不编译解决方法

问题如下 把文件复制进springboot项目后&#xff0c;没反应&#xff0c;不编译。 解决 在maven工具框中选择compile工具&#xff0c;运行即可。...

android jetpack App Startup 应用启动时初始化组件(java)

有什么用&#xff1f; 应用启动时初始化组件。 怎么用 添加依赖 dependencies {implementation "androidx.startup:startup-runtime:1.1.1" }创建类&#xff0c;继承Initializer。 public class AppInit implements Initializer<String> {NonNullOverride…...

【设计模式|行为型】命令模式(Command Pattern)

说明 命令模式&#xff08;Command Pattern&#xff09;是一种行为设计模式&#xff0c;它将请求封装为一个对象&#xff0c;以便在不同的请求者和接收者之间进行解耦、参数化和操作的队列化。命令模式允许你将具体的请求封装为对象&#xff0c;这些对象之间彼此独立&#xff…...

SqlServer 批量删除表

SqlServer 批量删除表 直接上SQL脚本吧 SELECT row_number()over(order by Name) as FID,Name into #temp FROM SysObjects Where XTypeU --类型&#xff0c;U为实体表 and name like TMP% --表名过滤&#xff08;自定义就好&#xff09; ORDER BY Namedeclare count int 0…...

[Linux]线程基本知识

概念 进程 一个正在执行的程序&#xff0c;它是资源分配的最小单位 进程中的事情需要按照一定的顺序逐个进行 进程出现了很多弊端: 一是由于进程是资源拥有者&#xff0c;创建、撤消与切换存在较大的时空开销&#xff0c;因此需要引入轻型进程&#xff1b; 二是由于对称多…...

STM32 串口基础知识学习

串行/并行通信 串行通信&#xff1a;数据逐位按顺序依次传输。 并行通信&#xff1a;数据各位通过多条线同时传输。 对比 传输速率&#xff1a;串行通信较低&#xff0c;并行通信较高。抗干扰能力&#xff1a;串行通信较强&#xff0c;并行通信较弱。通信距离&#xff1a;串…...

页面滚动时隐藏element-ui下拉框/时间弹框

场景 在系统中&#xff0c;当&#xff08;有垂直滚动时&#xff09;点击下拉框后滚动页面&#xff0c;会发现下拉项会遮盖住页面中的元素&#xff0c;不会隐藏 解决&#xff1a;(以vue为例) 在页面滚动或者缩放时隐藏下拉项即可&#xff08;借助点击目标元素&#xff0c;下…...

C#中i++和++i的底层原理

一&#xff1a;前言 我们都知道&#xff0c;i是先取值&#xff0c;后计算。i是先计算&#xff0c;后取值。下面说下它的底层原理 二&#xff1a;原理 int i 0; i; Console.WriteLine(i); 结果是1 执行步骤是&#xff1a; 1.将常量0压入栈中 2.从栈中取出元素0&#xff0c;局…...

在win10下安装verilator

主要参考文章 Verilator简介及其下载安装卸载_徐晓康的博客的博客-CSDN博客https://blog.csdn.net/weixin_42837669/article/details/114505364上面的文章可以解决大部分问题,但是可能是方案有些老了,已经安装最新的版本,下面对最新的版本安装提供解决方案 一 预备工作 安…...

java设计模式-建造者(Builder)设计模式

介绍 Java的建造者&#xff08;Builder&#xff09;设计模式可以将产品的内部表现和产品的构建过程分离开来&#xff0c;这样使用同一个构建过程来构建不同内部表现的产品。 建造者设计模式涉及如下角色&#xff1a; 产品&#xff08;Product&#xff09;角色&#xff1a;被…...

iOS开发-实现获取下载主题配置动态切换主题

iOS开发-实现获取下载主题配置动态切换主题 iOS开发-实现获取下载主题配置更切换主题&#xff0c;主要是通过请求服务端配置的主题配置、下载主题、解压保存到本地。通知界面获取对应的图片及颜色等。 比如新年主题风格&#xff0c;常见的背景显示红色氛围图片、tabbar显示新…...

react经验4:动态组件

什么是动态组件&#xff1f; 在页面的一小块区域切换显示不同的组件 实现方法 1.声明示例组件 //写在component1.tsx中 const Component1()>{return (<div>组件1</div>) } //写在component2.tsx中 const Component2()>{return (<div>组件2</div…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral&#xff08;热门工具 Ruff 的开发者&#xff09;推出的下一代高性能 Python 包管理器和构建工具&#xff0c;用 Rust 编写。它旨在解决传统工具&#xff08;如 pip、virtualenv、pip-tools&#xff09;的性能瓶颈&#xff0c;同时…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...

stm32wle5 lpuart DMA数据不接收

配置波特率9600时&#xff0c;需要使用外部低速晶振...