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 我拉你进群~

相关推荐
崔庆才丨静觅2 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60613 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了3 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅3 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅3 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅4 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment4 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅4 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊4 小时前
jwt介绍
前端
爱敲代码的小鱼4 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax