22-reducers和effects有什么区别和作用?

回顾

接上篇,上次我们在前端项目中,完成了用户权限和动态菜单的相关教程。那也就是说,其实我们可以慢慢步入正轨,所以近期思考了下如何设计此平台结构。

上次有提到我们把帐号创建放在了系统内部,那这样的话我们就需要一个团队管理模块。因此,我们需要重新罗列一下我们的团队管理模块。

首先

我们的用户角色还是不变,还是三种角色用户,分别为:超级管理员、组长、普通用户。由user表的role字段进行管理

其次

我们既然需要我们的团队模块管理,那就需要罗列新的团队模块规则。如:

  1. 所有人都可以看到我的团队模块
  2. 仅超级管理员和组长有新增团队权限

团队管理模块讲解

  1. 创建项目

    • 在Abandon中,您可以创建多个项目,以组织和管理不同的API。
    • 团队管理员可以通过「项目管理」->「新建项目」->「新建」,创建新的项目。
  2. 编辑项目

    • 您可以编辑项目的名称或项目图标,以更好地描述和标识项目。
    • 团队所有者/管理员可以进入已创建的项目,然后在「项目设置」->「基础设置」->「编辑」中进行编辑。
  3. 克隆项目

    • Apifox允许您克隆项目,这对于复制项目内容或将项目移到其他团队非常有用。
    • 通过「项目设置」->「基础设置」->「克隆」,您可以将项目克隆到当前团队或其他团队。
  4. 移动项目

    • 您可以将项目从一个团队移动到另一个团队,以更好地组织项目。
    • 通过「项目设置」->「基础设置」->「移动项目」,可以执行项目的移动操作。
  5. 删除项目

    • 警告:删除项目是不可逆操作,因此务必谨慎。
    • 您可以通过「项目设置」->「基础设置」->「删除」,将项目彻底删除。

请注意,上述功能点只是项目管理功能的一部分。Abandon可能提供更多的项目管理功能,以满足不同用户的需求。

一个困扰了好久的BUG(或者说是我对功能运用的不熟练)

BUG描述:

【后台管理】-【用户管理】-【用户列表】用户列表中总是获取不到用户

详解

在这之前,我们先看我两次提交代码的更改中,到底是哪些功能导致了这个问题的发生,而且更改了哪些代码之后,代码就可以正常运转。

结果

可以接到结果中,更改代码后,添加reducers相关操作之后,可以看到代码生效,功能正常。

教学开始

dva框架:理解和使用reducers和effects

dva是一个基于redux、redux-saga和React Router的轻量级前端框架,它简化了redux的使用,使得构建复杂应用的数据流变得更容易。在dva中,state更新的一切操作均在reducerseffects中完成。让我们深入了解一下这两个关键概念。

reducers

在dva中,reducers是纯函数,用来接受当前的状态(state)和动作(action),并返回新的状态。每当发出一个action,这个action将被匹配到的reducer函数接收,并返回一个新的state。它的作用是描述如何更新state。

javascript 复制代码
reducers: { 
    update(state, action) {
        return { ...state, ...action.payload }; 
    } 
}

上述例子中,update函数是一个reducer,它接受当前的状态(state)和一个动作(action),返回一个新的状态。动作(action)的payload属性通常包含了需要用于更新状态的数据。

effects

effects是在dva中处理异步操作的机制。如果你的函数需要进行如请求数据等异步操作,那么应该在effects中进行。它们是基于Redux-saga,是一种Generator Function(生成器函数)。

javascript 复制代码
effects: {
    *fetch(action, { call, put }) { 
        const data = yield call(service.fetch, action.payload);
        yield put({ type: 'update', payload: data }); 
    } 
}

在上述例子中,fetch函数是一个effect。它首先调用service.fetch函数来请求数据。由于这是一个异步操作,所以我们前面加了 yield 关键字,它会等待异步操作完成。然后,我们使用 yield put 来发出一个action,这将触发更新state的reducer函数。

reducers与effects的区别

基本上,reducerseffects都是用来更新state的,但使用的场景和方式有所不同。以下是他们的主要区别:

  1. reducers是同步的更新state,通常用来处理同步操作,比如更新一个数据列表、切换一个UI元素的显示/隐藏状态等。reducers是纯函数,它们不能进行任何异步操作或副作用。
  2. effects是用来处理异步操作的,比如获取服务器数据、处理并发操作等。effects是Generator函数,不同于reducerseffects中可以执行异步操作。
  3. effects可以触发reducers,但reducers不能触发effects。这么规定是因为,reducers需要保持为纯净的,并且不能有任何副作用。

结合项目

废话不多说,直接看更改点

const 复制代码
    namespace: 'user',
    state: {
        currentUser: {},
        userList: [],
        currentUserList: [],
        userMap: {},
        userNameMap: {},
        activities: [],
        operationLog: [],
        project_count: 0,
        case_count: 0,
        user_rank: 0,
        total_user: 0,
        weekly_case: [],
        followPlan: [],
    },
    effects: {
        *fetchUserList(_, { call, put }) {
            const response = yield call(listUsers);
            yield put({
                type: 'save',
                payload: {
                    userList: response.data.user_list,
                    currentUserList: response.data.user_list,
                },
            });
            // console.log(response.data.user_list);
        },
    },
    reducers: {
        save(state, {payload}) {
          return {...state, ...payload}
        }
  },
};

基础知识

  1. Dispatch: dispatch函数用来发起 action。无论你是调用effects,还是reducers,都依靠dispatch函数来发起。dispatch函数通常接受一个对象,该对象至少包含一个type属性(表示action名称),并且可能包含一个payload属性(表示传递给reducereffect的数据)。
php 复制代码
dispatch({
  type: 'user/fetchUserList', // 'namespace/effect或reducer名称'
  payload: {
    ...somePayloadData,
  },
});
  1. Namespace: 在dva中的namespace是全局state中的一个属性,它代表着特定的model。(model是dva中组织代码和数据的方式,包含statereducerseffectssubscriptions等)。每个model都有自己唯一的namespace,这样就可以在全局state中找到它。

  2. Subscriptions: subscriptions是监听源,它们在app.start()执行后被执行,它们通常用于监听路由的变化,键盘输入,WebSocket连接等等。然后根据需要dispatch相应的action。

javascript 复制代码
subscriptions: {
  setup({ dispatch, history }) {
    history.listen((location) => {
      dispatch({
        type: 'fetch',
        payload: location.query,
      });
    });
  },
},

以上就是dva框架中的一些基本概念。一旦你理解了如何使用actiondispatchreducereffect等来处理数据和状态,使用dva就变得非常直观和高效了。

在dva框架中,reducers和effects的执行顺序是怎样的?

在 dva 框架中,reducerseffects 的执行顺序主要取决于触发他们的 action。

当你通过dispatch发起一个 action 时,dva 会根据这个 action 的 type 来决定应该触发哪个 effect 或者 reducer。每个 effectreducer 都有一个唯一的 type,这个 type 就是它们的名字。

如果你的 action 的 type 对应一个 effect,那么 dva 就会运行这个 effect。在 effect 内部,你可以进行异步操作,然后可能会用 put 发起另一个 action。

例如:

javascript 复制代码
effects: {
    *fetchList(action, { call, put }) {
        const response = yield call(api.fetchList);
        yield put({ type: 'save', payload: response });
    },
}

在这个例子中,当你触发 fetchList 这个 effect 后,它会先调用 api.fetchList 来获取数据,然后再发起一个类型为 save 的 action。

如果你的 action 的 type 对应一个 reducer,那么 dva 就会调用这个 reducer 来处理这个 action,并返回一个新的 state。

例如:

javascript 复制代码
reducers: {
    save(state, action) {
        return { ...state, list: action.payload };
    },
}

在这个例子中,当你触发 save 这个 reducer 后,它会根据这个 actionpayload 来修改 state

所以,说到 reducerseffects 的执行顺序,实际上是由你发起的 action 来决定的。你可以在 effect 中发起其他的 action,从而使得 effect 先执行,然后再触发 reducer。另一方面,如果你直接发起一个对应 reducer 的 action,那么 reducer 就会先执行。

开源相关

组织地址

后端代码地址

前端代码地址

加群一起讨论相关问题呀!如果群二维码过期了,可以加我个人微信: yyi11yy 我拉你进群~

相关推荐
云深时现月1 分钟前
jenkins使用cli发行uni-app到h5
前端·uni-app·jenkins
昨天今天明天好多天8 分钟前
【Node.js]
前端·node.js
2401_8576100331 分钟前
深入探索React合成事件(SyntheticEvent):跨浏览器的事件处理利器
前端·javascript·react.js
雾散声声慢43 分钟前
前端开发中怎么把链接转为二维码并展示?
前端
熊的猫43 分钟前
DOM 规范 — MutationObserver 接口
前端·javascript·chrome·webpack·前端框架·node.js·ecmascript
天农学子44 分钟前
Easyui ComboBox 数据加载完成之后过滤数据
前端·javascript·easyui
mez_Blog44 分钟前
Vue之插槽(slot)
前端·javascript·vue.js·前端框架·插槽
爱睡D小猪1 小时前
vue文本高亮处理
前端·javascript·vue.js
开心工作室_kaic1 小时前
ssm102“魅力”繁峙宣传网站的设计与实现+vue(论文+源码)_kaic
前端·javascript·vue.js
放逐者-保持本心,方可放逐1 小时前
vue3 中那些常用 靠copy 的内置函数
前端·javascript·vue.js·前端框架