> 技术文档 > React状态管理——Dva

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# 或者使用 yarnyarn 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.jsapp.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. Initializeconst app = dva({ history: createHistory(),});// 2. Plugins (可选)// app.use({});// 3. Model (可以在这里注册全局model)// app.model(require(\'./models/example\').default);// 4. Routerapp.router(() => );// 5. Startapp.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 ( 

Count: {count}

);}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 ( 

Count: {count}

);}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(() => { // 动态加载 model app.model(require(\'../models/counter\').default); // 组件卸载时取消注册 model(可选) return () => { app.unmodel(\'counter\'); }; }, [app]); return ( 

Count: {count}

);}

方法二:使用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(() => { // 动态加载 model dispatch({ type: \'@@dva/dynamicLoad\', payload: { models: () => [import(\'../models/counter\')], }, }); return () => { // 可以在这里取消 model(如果需要) }; }, [dispatch]); return ( 

Count: {count}

);}