React状态管理——Dva

目录

一、安装依赖

二、Dva注册model方式

2.1 自动注册models

2.2 手动注册model方式

三、创建 dva 实例

四、创建 model

五、在组件中使用

六、动态加载Dva Model


Dva 是一个基于 redux 和 redux-saga 的轻量级前端框架,可以方便地在 React 应用中管理状态。下面是将 Dva 接入 create-react-app 项目的步骤:

一、安装依赖

        在react-react-app项目目录中安装 dva 相关依赖:

npm install dva --save
# 或者使用 yarn
yarn add dva

二、Dva注册model方式

2.1 自动注册models

        Dva 本身不会自动识别特定的 models 文件夹或 model.js 文件,但官方推荐以下约定俗成的结构:

src/├── models/          # 全局 model 目录│   ├── user.js      # 用户 model│   └── product.js   # 产品 model└── pages/├── Home/│   ├── model.js # 页面级 model (可选)│   └── index.js└── About/├── model.js└── index.js

2.2 手动注册model方式

        Dva 需要显式注册 model 才会生效,主要有以下几种注册方式:

  • 初始化时注册
// src/index.js
app.model(require('./models/user').default);
  • 动态注册
// 在组件或路由加载时
useEffect(() => {app.model(require('./models/product').default);
}, []);

三、创建 dva 实例

修改 src/index.js 文件:


import React from 'react';
import dva from 'dva';
import createHistory from 'history/createBrowserHistory';
import App from './App';
import './index.css';// 1. Initialize
const app = dva({history: createHistory(),
});// 2. Plugins (可选)
// app.use({});// 3. Model (可以在这里注册全局model)
// app.model(require('./models/example').default);// 4. Router
app.router(() => <App />);// 5. Start
app.start('#root');

四、创建 model

在 src/models 目录下创建一个 model 文件,例如 counter.js

// 标准的 model 文件示例 (models/counter.js)
//export default {
//  namespace: 'user',  // 必须的唯一标识
//  state: {},         // 必须的初始状态
//  reducers: {},      // 同步修改 state 的方法
//  effects: {},       // 异步处理逻辑
//  subscriptions: {}  // 订阅数据源
//};export default {namespace: 'counter',state: {count: 0,},reducers: {add(state) {return { ...state, count: state.count + 1 };},minus(state) {return { ...state, count: state.count - 1 };},},effects: {*addAsync(_, { call, put }) {yield call(delay, 1000);yield put({ type: 'add' });},},
};function delay(timeout) {return new Promise(resolve => {setTimeout(resolve, timeout);});
}

五、在组件中使用

方法一:connect

import React from 'react';
import { connect } from 'dva';function Counter({ count, dispatch }) {return (<div><h2>Count: {count}</h2><button onClick={() => dispatch({ type: 'counter/add' })}>+</button><button onClick={() => dispatch({ type: 'counter/minus' })}>-</button><button onClick={() => dispatch({ type: 'counter/addAsync' })}>Add Async</button></div>);
}function mapStateToProps(state) {return {count: state.counter.count,};
}export default connect(mapStateToProps)(Counter);

方法二:React Hooks(useSelector、useDispatch)

import React from 'react';
import { useSelector, useDispatch } from 'dva';function Counter() {// 使用 useSelector 获取 state 中的 counter 数据const count = useSelector(state => state.counter.count);// 使用 useDispatch 获取 dispatch 方法const dispatch = useDispatch();return (<div><h2>Count: {count}</h2><button onClick={() => dispatch({ type: 'counter/add' })}>+</button><button onClick={() => dispatch({ type: 'counter/minus' })}>-</button><button onClick={() => dispatch({ type: 'counter/addAsync' })}>Add Async</button></div>);
}export default Counter;

六、动态加载Dva Model

方法一:使用useEffect + app.model()

import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'dva';export default function CounterPage() {const dispatch = useDispatch();const count = useSelector(state => state.counter.count);useEffect(() => {// 动态加载 modelapp.model(require('../models/counter').default);// 组件卸载时取消注册 model(可选)return () => {app.unmodel('counter');};}, [app]);return (<div><h2>Count: {count}</h2><button onClick={() => dispatch({ type: 'counter/add' })}>+</button></div>);
}

方法二:使用dynamic

import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'dva';export default function CounterPage() {const dispatch = useDispatch();const count = useSelector(state => state.counter.count);useEffect(() => {// 动态加载 modeldispatch({type: '@@dva/dynamicLoad',payload: {models: () => [import('../models/counter')],},});return () => {// 可以在这里取消 model(如果需要)};}, [dispatch]);return (<div><h2>Count: {count}</h2><button onClick={() => dispatch({ type: 'counter/add' })}>+</button></div>);
}

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

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

相关文章

编程与数学 03-002 计算机网络 05_以太网技术

编程与数学 03-002 计算机网络 05_以太网技术一、以太网的基本原理&#xff08;一&#xff09;CSMA/CD协议的工作原理&#xff08;二&#xff09;以太网的帧结构二、以太网的拓扑结构与设备&#xff08;一&#xff09;传统以太网的拓扑结构&#xff08;二&#xff09;交换机的工…

解决英文版Windows10安装WireShark报错

问题点击WireShark安装包进行安装时报错原因编码方式故障解决方式修改操作系统编码1.WinR&#xff0c;输入Control&#xff0c;打开控制面板2.点击Small icons3.点击Region4.设置编码UTF-8

利用aruco标定板标定相机

1、生成aruco标定板#include <opencv2/opencv.hpp> #include <opencv2/aruco.hpp> #include <opencv2/objdetect/aruco_detector.hpp> #include <iostream> #include <string>using namespace cv; using namespace std;int main() {int markers…

C/C++语言程序使用三种主要的内存分配方式,和python语言一样么?

这是一个很好的比较问题&#xff01;C/C 和 Python 在内存分配方式上有本质的区别&#xff0c;虽然它们最终使用的都是计算机的物理内存&#xff08;堆、栈等&#xff09;&#xff0c;但语言层面提供的抽象和管理机制完全不同。核心区别&#xff1a;控制权&#xff1a; C/C 程序…

小电流驱动大电流:原理、实现方式与应用前景

目录 一、什么是“小电流驱动大电流”&#xff1f; 举个例子&#xff1a; 二、核心原理与实现方式 1. 电流放大原理 2. 电子开关元件 3. 控制电路设计 4. 附加保护措施 三、为什么采用“小电流驱动大电流”&#xff1f; 1. 提高安全性 2. 降低能耗 3. 改善效率 4. …

【DM数据守护集群搭建-读写分离】

DM数据守护集群搭建-读写分离 读写分离集群由一个主库以及一个或者多个配置了即时&#xff08;Timely&#xff09;归档或实时&#xff08;Realtime&#xff09;归档的备库组成&#xff0c;其主要目标是在保障数据库可用性基础上&#xff0c;实现读、写操作的自动分离&#xff0…

earth靶场

1、找ip和端口主机是192.168.6.213&#xff0c;因此靶场ip就是192.168.6.34&#xff0c;三个端口开放&#xff0c;我们去访问一下页面。三个端口都无法访问。我们使用nmap进行dns解析。nmap -A -p- -T4 -sV 192.168.6.34把这两条解析添加到hosts文件中去&#xff0c;这样我们才…

Kafka——Java消费者是如何管理TCP连接的?

引言在分布式消息系统中&#xff0c;网络连接是数据流转的"血管"&#xff0c;其管理效率直接决定了系统的吞吐量、延迟与稳定性。作为Kafka生态中负责数据消费的核心组件&#xff0c;Java消费者&#xff08;KafkaConsumer&#xff09;的TCP连接管理机制一直是开发者理…

idea监控本地堆栈

idea 安装插件 VisualVM Launcher重启idea后&#xff0c;配置 VisualVM 属性选择自己jdk的 jvisualvm启动时&#xff0c;选择监控&#xff0c;会自动弹出 VisualVM

系统性提升大模型回复准确率:从 RAG 到多层 Chunk 策略

大语言模型&#xff08;LLM&#xff09;在问答、搜索、对话等任务中展现出强大的生成能力&#xff0c;但它并不具备真实世界知识的完全记忆与对齐能力&#xff0c;尤其在涉及复杂信息、长文档引用或领域细节时&#xff0c;其“幻觉”问题&#xff08;hallucination&#xff09;…

【神经网络概述】从感知机到深度神经网络(CNN RNN)

文章目录1. 神经网络基础1.1 感知器&#xff08;Perceptron)1.2 深度神经网络&#xff08;DNN&#xff09;2. 卷积神经网络&#xff08;CNN&#xff09;2.1 核心思想2.2 典型结构2.3 ⾥程碑模型:2.4 卷积层 - CNN 核心2.5 池化层3. 循环神经网络&#xff08;RNN&#xff09;3.1…

界面规范3-列表下

4、内容文字有链接的采用蓝色字体<font colorblue></font>重要内容采用红字字体&#xff0c;如状态<font colorred></font>一般字体使用color: #3232325、行高height: 40px;line-height: 40px;6、其他表格占满界面空间&#xff0c;内容多时&#xff0c…

中文语音识别与偏误检测系统开发

中文语音识别与偏误检测系统开发 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff0c;觉得好请收藏。点击跳转到网站。 1. 系统概述 本系统旨在开发一个基于Paraformer模型的中文语音识别与偏误检…

MySQL创建普通用户并为其分配相关权限的操作步骤

1. 登录MySQL服务器 首先&#xff0c;你需要以管理员身份登录MySQL服务器。可以使用以下命令&#xff1a; mysql -u root -p 输入密码后&#xff0c;即可进入MySQL命令行界面。 2. 创建新用户 使用CREATE USER语句创建新用户。语法如下&#xff1a; CREATE USER usernamehost I…

OSPF 路由协议多区域

一、课程目标本课程旨在帮助学习者掌握 OSPF 多区域的核心知识&#xff0c;具体包括&#xff1a;掌握 OSPF 各种 LSA 的内容和传递过程、了解普通区域与特殊区域的特点、掌握 OSPF 多区域的配置。二、OSPF 多区域划分的必要性单区域存在的问题单区域 OSPF 网络中&#xff0c;存…

小程序的客服咨询(与企业微信建立沟通)

背景&#xff1a;小程序是面向群众的。需要提供与企业的聊天窗口。 一、连接方式。 使用组件的方式最佳wx.openCustomerServiceChat 二、接入小程序 链接

解码3D格式转换

三维图形与可视化领域&#xff0c;3D模型格式作为数据交换与存储的基石&#xff0c;承载着模型结构、几何形状、纹理以及材质等多重信息。不同的3D模型格式在支持材质的方式上各有差异&#xff0c;这些差异不仅影响模型的外观表现&#xff0c;还在格式转换过程中带来了特定的挑…

HarmonyOS学习记录5

HarmonyOS学习记录5 本文为个人学习记录&#xff0c;仅供参考&#xff0c;如有错误请指出。本文主要记录网络请求的开发知识。 参考文档&#xff1a;HTTP和RCP访问网络 网络连接 概述 网络连接管理提供管理网络一些基础能力&#xff0c;包括WiFi/蜂窝/Ethernet等多网络连接优…

【C/C++】explicit_bzero

explicit_bzero explicit_bzero 是一个为了解决 memset 在安全清除内存场景中可能被优化器移除的问题而设计的函数&#xff0c;广泛用于安全编程中&#xff0c;比如密码、密钥清除等。Introduce 头文件 #include <string.h>函数原型 void explicit_bzero(void *s, size_t…

MySQL 链接方法思考

代码: import subprocess import os from dotenv import load_dotenv import pymysql from sqlalchemy import create_enginedef check_mysql_service():"""检查 MySQL 服务是否运行"""try:result = subprocess.run(["systemctl", &…