前端-Umi Dva使用

Umi Dva入门使用,含详细解释

view和model的关系图

在这里插入图片描述

model属性

model主要有 namespace state reducers effects subscription5个主要属性。

namespace:定义model名,如果没声明,会以文件名作为namespace。

state:model 的状态。

reducers:reducer 是 Action 处理器,用来处理同步操作。如果不需要调接口时候,我们前台传递的 action 可以直接调用 reducers 里的方法。必须返回一个新的state,否则不会自动更新页面。

effects: Effect用来处理异步操作。内部是一个 Generator 函数,使用 yield 关键字,标识每一步的操作。dva 提供多个 effect 函数内部的处理函数,比较常用的是 callput

  • call:执行异步函数,比如发送请求
  • put:发出一个 Action,类似于 dispatch

subscriptions:相当于一个监听器,可以监听路由的变化、鼠标、键盘、服务器连接变化等。subscriptions的方法会自动初始化(执行一遍)。

model基本结构

export default {
  namespace: 'myglobal', // 定义model名,如果没声明,会以文名件作为namespace
  state: {obj: []}, // 该 model 当前的状态
  // reducer 是 Action 处理器,用来处理同步操作。如果不需要调接口时候,我们前台传递的 action 可以直接调用 reducers 里的方法。
  reducers: {
    /**
     * queryEnd方法名自定义
     * @param {Object} state 旧的state
     * @param {Object} payload 存放在 action 里面的数据
     * @param {String} propsName 字段名
     * @return {Object} 新的state。(直接重新return一个新的state会丢弃旧的state,所以为了保留旧的state,一般会解构旧的state再合并新的state)
     */
    queryEnd(state, { payload, propsName }) {// 第二个参数为 action = {type,payload}
      return { ...state, [propsName]: payload };
    }
  },
  // Effect用来处理异步操作。内部是一个 Generator 函数,使用 yield 关键字,标识每一步的操作。
  // 如果需要调取接口的话,前台页面就需要调用 effects 里的方法。将数据取出来,再传递给 reducers 里的方法进行数据操作和同步 state。
  effects: {
    /**
     * queryResolved方法名自定义
     * @param {String} propsName 保存在state中的字段名
     * @param {Object} payload 存放在 action 里面的数据
     * @param {function} callback 回调函数
     * @param {function} call dva提供处理异步任务 (与后台服务端接口进行交互)
     * @param {function} put dva提供用来发出action (action可以是异步的effects、同步的reducers)
     * @param {function} select dva提供调用其他model层的state
     * @return {null} 无返回
     */
      *queryResolved({ propsName, payload, callback }, { call, put, select }) {
      try {
        const response = yield call(queryResolvedFetch, payload); // 第一个传参:后台服务器接口对应的名称。第二个参数:入参。
        const homeName = yield select(state => state.home); // 这样我们就可以取到名为 home 的 Model 层里面的 state 数据了。
        yield put({
          type: 'queryEnd',
          payload: response.data.records,
          propsName: propsName
        });
        if (callback) callback(response.data.records);
      } catch (e) {
        console.log('queryResolved异常:', e);
      }
    }
  },
  // subscriptions相当于一个监听器,可以监听路由的变化、鼠标、键盘、服务器连接变化等。subscriptions的方法会自动初始化(执行一遍)。
  subscriptions: {

    setup({ dispatch, history }) {
      console.log('setup');
      window.onresize = () => {   //这里表示的当浏览器的页面的大小变化时就会触发里面的dispatch方法,这里的save就是reducers中的方法名
        dispatch({ type: 'save' })
      }
    },
    onClick ({dispatch}) {
      console.log('onClick');
      document.addEventListener('click',() => {   //这里表示当鼠标点击时就会触发里面的dispatch命令,这里的save就是reducers中的方法名
        dispatch ({ type: 'save' })
      })
    }
  },
};

使用connect将Route页面与Model state 进行绑定

connect是dva提供的api,但在umi3也可以这样导入:import { connect } from “umi”;

import React, { useEffect } from "react";
import { connect } from "umi";

function IndexPage(props) {
  useEffect(() => {
    props.dispatch({
      type: `myglobal/getList`,
      payload: { page: 1, size: 5 },
    });
  }, []);

  return (
    <div></div>
  );
}

IndexPage.propTypes = {};

export const mapStateToProps = ({myglobal}) => {
  return { myglobal }; // myglobal 是 Model 层里面的 namespace
};
export default connect(mapStateToProps)(IndexPage);

使用useSelector将Route页面与Model state 进行绑定

import React, { useEffect } from "react"
import { shallowEqual } from 'react-redux'
import { useDispatch, useSelector } from "umi"

export default function IndexPage(props) {
  const dispatch = useDispatch();
  const commomState = useSelector((state) => {
    return state.myglobal;
  },shallowEqual);
  
  useEffect(() => {
    setTimeout(() =>{
      dispatch({
        type: "myglobal/queryEnd",
        payload: {obj: []}
      })
    }, 3000)
  }, [])

  const count = (date) => {
    console.log('count', commomState, date);
  }

  return (
    <div>
      <h1>Page index</h1>
      <h2>{count(new Date().getTime())}</h2>
      <h3>{new Date().getTime()}</h3>
    </div>
  );
}

useSelector和shallowEqual

useSelector:从umi导出的useSelector实质是react-redux的api,默认使用===做浅比较,第二个参数是一个函数用于自己实现比较逻辑(返回true不刷新组件,返回false刷新)。
shallowEqual:react-redux提供的api,用于优化组件重新渲染的次数。

初始化		改变后的值			是否加shallowEqual	是否刷新组件
111			111					否					否

{}			{}					否					是
{}			{}					是					否
{}			{test: "test"}		是					是
{}			{test: "test"}		否					是

{obj: "aaa"} {obj: "aaa"}		是					否
{obj: "aaa"} {obj: "bbb"}		是					是
{obj: []}	{obj: []}			是					是
{obj: {name: "aaa"}} {obj: {name: "aaa"}} 是		是


[1,2]		[1,2]				否					是
[1,2]		[1,2]				是					否
[1,2]		[2,2]				是					是

总的来说:
useSelector默认会比较引用
shallowEqual第一层是值比较,第二层会比较引用

使用React、Umidva组合开发Web应用时,你需要遵循一系列步骤来构建和组织你的项目。这里是一个基本的介绍: 1. **创建项目**:首先,你需要创建一个新的Umi项目。Umi是一个可插拔的企业级React应用框架,它可以帮助你快速搭建项目结构,并提供了一些约定和最佳实践。你可以通过命令行使用Umi的脚手架工具来创建新项目: ``` npx umi init my-app cd my-app ``` 2. **安装dva**:dva是一个轻量级的前端框架,它基于Redux和Redux-Saga,提供了一种更简洁的方式来组织你的应用状态和处理数据流。在项目中安装dva: ``` npm install dva ``` 3. **配置路由**:Umi使用约定式路由,你只需要在`src`目录下创建对应的文件和目录来定义你的页面和路由。例如,创建一个`pages`文件夹,并在其中创建`user.js`文件,这将会被识别为一个用户页面,并且对应的路由会被自动生成。 4. **使用dva模型**:在dva中,模型(model)是应用中数据和逻辑的抽象。你需要定义模型来管理状态,并且定义effect来处理异步逻辑。在Umi项目中,你可以创建一个`models`目录来存放你的dva模型。 5. **连接视图和模型**:在React组件中,你可以使用`connect`方法来连接组件和dva模型。这样,你的组件就可以访问模型中的状态,并且可以触发模型中的dispatch来更新状态。 6. **数据流管理**:在dva中,使用Redux的`dispatch`来触发一个action,然后action会调用对应的reducer来更新状态,或者调用effect来处理异步逻辑。这是一个单向数据流的过程,有助于维护状态的一致性和可预测性。 7. **启动和构建项目**:在开发过程中,你可以使用以下命令来启动开发服务器: ``` npm start ``` 当你需要构建项目用于生产环境时,可以使用: ``` npm run build ``` 这将会生成优化后的静态文件,可以部署到任何静态文件服务器上。 这些步骤为你提供了如何使用React、Umidva组合进行Web应用开发的基础。随着项目的深入,你可能还需要了解更多的高级特性,比如插件、中间件、路由配置、布局组件等。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值