React中Dva状态管理(model)的使用总结和理解

一 概述

React中全局状态管理官方推荐使用Redux,Redux的使用场景其实在单个应用中是处于使用率只有20%,却有80%的学习成本。可是说是React全家桶中最难理解的部分了,相信很多人学习它时,各个概念整很迷糊。我就是要放弃Redux的时候,了解React-redux和redux-saga, 它们是对redux的简化处理工具。可他们配置和文件结构,依然麻烦。直到Dva(低洼)的出现将React全局状态管理简化到了极致。那么今天带大家一起快速学习下Dav中全局状态的使用技巧,本篇文章仅仅是对使用方式的个人理解。

由于时间关系,测试内容可能有误,请看官主要理解总结中的内容。

二 环境搭建

本次演示环境使用UmiJs搭建,因为Dva已经很久不维护了,并且已经交由Umi管理,所以使用Umi来创建React项目是目前最方便的。参考官网环境搭建好后:如下

 三 使用

3.1 创建model文件

默认src/models下创建的所有符合model规范的文件都会自动注册到umijs中。创建src/models/users.js,

import {apiUserList} from '@service/user.js'
export default {
    namespace: 'users',
    state: {
        name: ''
    },
    effects: {
        *fetchUserName({ payload }, { call, put }) {
            const userName = yield call(apiUserList, payload)
            yield put({ type: 'setName', payload: userName })
        },
    },
    reducers: {
        setName(state, { payload }) {
            return {
                ...state,
                name: payload
            };
        },
    },
};

 创建src/pages/user.jsx

import React from 'react';
import { connect } from 'dva';

const users = ({ dispatch, userName }) => {
  const setUserName = () => {
    dispatch({
      type: 'users/setName',
      payload: '我小桃',
    });
  };

  return (
    <>
      <div>用户页面{userName}</div>
      <button onClick={setUserName}>点我修改</button>
    </>
  );
};

const mapStateToProps = (state) => {
  console.log(state);
  return {
    userName: state.users.name,
  };
};

export default connect(mapStateToProps)(users);

运行yarn start

个人使用总结:

model的使用

1. namespace

【命名空间】是外部分发(dispatch)调用model时,actions里type属性的前缀,后面跟reducerseffect的方法名。使用示例如下。model内部调用方法使用时可是省略前缀。

dispatch({
  type: 'users/setName',
  payload: '我小桃',
})

2. state

存储全局变量的仓库,核心使用的就是state,却是最简单理解的。结构对象和数组都可。

3. reducers

方法签名(state是状态,payload是分发时传的参数)

setName(state, { payload }) {}

唯一操作state的地方(CURD),即可对内(effects使用)也可对外。外部想要写state可以直接dispatch到reducers的方法来进行操作state。由于外部组件通过connect后可以获取(读)state的值,所以写操作必须使用dispatch。当然如果外部组件涉及到异步操作,比如删除用户是异步的话,这种情况往往实践都是直接dispatch到effects方法。而effects方法要处理需要分两步走:(1)调用异步接口删除用户数据(2)model内部dispatch到reducers的方法,让reducers删除state数据。

4. effects

使用示例

*fetchUserName({ payload }, { call, put }) {
  const userName = yield call(apiUserList, payload)
  yield put({ type: 'setName', payload: userName })
},

最佳实践,一般是做异步业务CRUD,调用接口后再调用reducers中的方法来重新设置state。往往是方便外部组件使用,外部只调用effects方法就完成2部操作操作接口和操作state。其实也可以外部组件自己调用异步接口,之后再dispatch到reducers,这样就能省下一个effects,看个人喜好推荐使用effects。

方法签名(①payload是外部dispatch时传的参数;②call是可以调用接口的方法,call调用接口时第一个参数是调用接口的方法名称,第二个参数是调用接口的参数;③put是effects特有的方法,类似外部调用的dispatch。dispatch和put参数数都是Action对象(Action对象包含type属性和payload属性)


外部组件使用model

1. 引入dva连接器

import { connect } from 'dva';

2. 使用连接器连接组件

export default connect(mapStateToProps)(组件名称);

3. 定义一个model中的state转为组件props的方法(方法返回值会赋值给props);

const mapStateToProps = (state) => {
  console.log(state);
  return {
    userName: state.users.name,
  };
};

4. 组件props自带dispatch方法和第三步转化后的属性

使用state

组件内部如果使用state,可以直接通过转化方法间接使用state。

const 组件 = ({ dispatch, userName }) => {
    
}

操作state

(1)如果需要异步修改数据库和state则可以dispatch到effects方法

(2)如果仅仅修改state不做接口调用,则dispatch到reducers方法即可。

dispatch({
  type: '[namespace]/effects或reducers的方法名称',
  payload: '我小桃',
});

(完~)

React使用dvamodel,首先需要了解dva是一个基于Redux和Redux-Saga的轻量级框架,它封装了Redux和Redux-Saga的复杂性,提供了一种更简洁的方式来组织应用的状态管理。在函数式组件,通常会用到`useSelector`和`useDispatch`这两个Hooks来接入dvamodel。 以下是基本步骤: 1. 安装dva及其依赖项: ```bash npm install dva-core ``` 或者使用yarn: ```bash yarn add dva-core ``` 2. 使用`useDispatch` Hook来获取dispatch函数,然后调用model里面定义的namespace对应的reducers或saga: ```javascript import React from 'react'; import { useDispatch } from 'react-redux'; // 如果使用react-redux版本dva import { useModel } from 'dva-core'; // 如果直接使用dva-core function MyComponent() { const dispatch = useDispatch(); // 或者使用 dva 的方式获取dispatch // const { dispatch } = useModel('app'); // 假设有一个model定义了namespace为'counter',里面有reducer和saga const counterModel = useModel(state => state.counter); // 使用dispatch调用action const increase = () => { dispatch({ type: 'counter/increase', }); }; // 使用model的state数据 return ( <div> <p>{counterModel.count}</p> <button onClick={increase}>Increase</button> </div> ); } export default MyComponent; ``` 在这个例子,我们通过`useDispatch` Hook来获取Redux的dispatch函数,然后通过发送一个action来更新状态。而`useModel` Hook可以获取到model定义的state状态。 3. 在dvamodel定义namespace,reducer和saga: ```javascript // model定义 app.model({ namespace: 'counter', state: { count: 0, }, reducers: { increase(state) { return { ...state, count: state.count + 1 }; }, }, effects: { *decrease(action, { put }) { yield put({ type: 'increase' }); }, }, }); ``` 确保你的dva实例被正确创建并且在应用使用。通常,这是通过将你的根组件包裹在`<Provider>`标签内完成的。 ```javascript import { Provider } from 'react-redux'; // 如果使用react-redux版本dva import { Router, Route } from 'dva/router'; // 如果直接使用dva-core import React from 'react'; import ReactDOM from 'react-dom'; import dvaApp from './dva'; const { app, router } = dvaApp; ReactDOM.render( <Provider store={app._store}> {router} </Provider>, document.getElementById('root') ); ``` 请注意,如果你使用的是`dva-core`,那么你需要使用dva-core提供的`Router`和`Route`组件。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值