基于MVC理解React+Redux

简介: 基于MVC理解React+Redux

image.png

我认为MVC模式虽然已经诞生了许多年,也有无数前端框架遵循了MVC模式,但我们在前端开发时,很多时候还是忽略了这个模式蕴含的思想。该思想的核心就是职责分离,这种分离又隐含了“信息专家模式”的意义,直白地说,就是“专业的事情应该交给专业的人去做”。

MVC(Model-View-Controller)的三个角色其实是各司其职:

  • model持有UI要展现的数据
  • View即UI的展现
  • Controller用于控制

以React来说,它就应该只专注于View的呈现,并将这些展现元素封装为Component。这些Component要展现的props可以视为Model所持有的数据。

那么,什么情况下会导致View产生变化呢?从表象上看,似乎引起变化的原因是由于客户端的某种请求或交互操作产生的事件。实则从业务上说,其实就是要改变Model的值,而UI的交互操作不过是对这种变化的界面展现罢了。换言之,View的变化其实应该通过Model的变化来传递。

当我们需要改变View时,一种做法是直接在View上做文章,通过编写针对UI元素的控制逻辑去改变View。另一种做法就是遵循MVC模式,应该通过Controller去改变Model的结构,然后通知View去改变自己(或者理解为View侦听到Model的变化,从而改变自己)。

React结合Redux框架做的正是这样的事情。在设计React Component时,我们需要通过UI的Layout来规划我们的Component,包括Component的分解与组合。呈现Component的过程就可以抽象为一个函数,这个函数接收一个输入对象model,返回一个包裹了HTML元素与Model的DOM结构。如以下伪代码:

const render = (model) => DOM

如果业务逻辑要求操作View的DOM,其实就是对DOM包裹的Model进行操作,例如添加或修改某个<li>,其本质是要添加或修改<li>元素中的值,这个值来自于Model。在Redux中,其实就是发起一个action。

执行action的目的虽然是修改Model,不过在Redux中,我们尽量希望遵循FP的思想设计出所谓的“纯函数”,于是Redux就引入了reducer函数,这个函数要做的事情其实就是对Model进行transform(可以考虑引入immutable.js来存储和操作Modle)。一旦Model对象发生了变化(并不是真正发生了变化,而是产生了一个新的Model),Redux就会通知React Component根据新获得的Model去重新Render。

显然,React扮演的是View的角色,Redux则是Controller,至于Model就是Redux Store中存储的State。我们要从MVC模式的角度去思考React+Redux开发,把代码需要做的每件事情想清楚,明确是谁的职责,如此才不至于在实现时走歪路,不讨好地去编写大量View的控制逻辑,尤其是那些牵涉到parent-child组件的递归关系时,可能会让前端代码炖成一锅粥。

举个实例。

我们要在前端编写一个过滤器,UI展现与控制逻辑类似Logiform,如下图所示:

image.png

△ Logiform的过滤器

这个过滤器可以理解为以Condition为根的一个递归嵌套树形结构,枝为Group,而叶为Expression。Group还可以嵌套Group或者Expression。可以添加、删除Group或Expression,也可以调整它们在树中所处的位置。

针对这样的需求,如果我们企图在React Component中直接去操控和管理这些逻辑,就需要考虑Component的父子关系,还需要考虑添加或删除Dom节点对整棵树的影响。

如果我们站在前述MVC模式的角度来考虑过滤器树的呈现与界面控制,其实不过就是针对Condition对象模型的操作罢了。这个时候,我们可以不用去操心DOM节点之间的关系,而是直接用React Component去render模型对象。对象的粗略结构如下所示:

{
    "id": 1,
    "operator": "and",
    "conditions": [
        {
            "id": 2,
            "type": "expression",
            "operator": "=",
            "fieldId": "11000",
            "value": 3
        },
        {
            "id": 3,
            "type": "group",
            "operator": "or",
            "conditions": [
                {
                    "id": 4,
                    "type": "expression",
                    "operator": "<=",
                    "fieldId": "11001",
                    "value": 20
                }
            ]
        }
    ]
}

由于render是一种只读的操作,要在React Component中去render这样的结构是非常容易的。如上,当我们要删除id为2的Expression时,其实就是去编写一个reducer,将其转换为如下的对象:

{
    "id": 1,
    "operator": "and",
    "conditions": [
        {
            "id": 3,
            "type": "group",
            "operator": "or",
            "conditions": [
                {
                    "id": 4
                    "type": "expression",
                    "operator": "<=",
                    "fieldId": "11001",
                    "value": 20
                }
            ]
        }
    ]
}

render对UI的呈现与控制逻辑完全相同,并不需要再去控制复杂的DOM。

概括下来,React+Redux的主体流程为:

  • 通过action获得model,并将其作为state存储到Store中;
  • 传递给React Component,按照某种设计呈现model数据;
  • 调用action发起update请求,从而调用reducer生成新的state存储到Store中;
  • redux通知React Component重新Render。

这是MVC三种角色各司其职相互协作的结果。

相关文章
|
4月前
|
前端开发 JavaScript 测试技术
从零开始搭建react+typescript+antd+redux+less+vw自适应项目
从零开始搭建react+typescript+antd+redux+less+vw自适应项目
141 0
|
1月前
|
存储 JavaScript 前端开发
React中使用redux
React中使用redux
128 56
|
29天前
|
存储 JavaScript 前端开发
react redux 实现原理
【8月更文挑战第29天】react redux 实现原理
18 4
|
27天前
|
前端开发 Java UED
瞬间变身高手!JSF 与 Ajax 强强联手,打造极致用户体验的富客户端应用,让你的应用焕然一新!
【8月更文挑战第31天】JavaServer Faces (JSF) 是 Java EE 标准的一部分,常用于构建企业级 Web 应用。传统 JSF 应用采用全页面刷新方式,可能影响用户体验。通过集成 Ajax 技术,可以显著提升应用的响应速度和交互性。本文详细介绍如何在 JSF 应用中使用 Ajax 构建富客户端应用,并通过具体示例展示 Ajax 在 JSF 中的应用。首先,确保安装 JDK 和支持 Java EE 的应用服务器(如 Apache Tomcat 或 WildFly)。
30 0
|
27天前
|
存储 JavaScript 前端开发
探索React状态管理:Redux的严格与功能、MobX的简洁与直观、Context API的原生与易用——详细对比及应用案例分析
【8月更文挑战第31天】在React开发中,状态管理对于构建大型应用至关重要。本文将探讨三种主流状态管理方案:Redux、MobX和Context API。Redux采用单一存储模型,提供预测性状态更新;MobX利用装饰器语法,使状态修改更直观;Context API则允许跨组件状态共享,无需第三方库。每种方案各具特色,适用于不同场景,选择合适的工具能让React应用更加高效有序。
41 0
|
1月前
|
存储 JavaScript 前端开发
"探索Redux的Vuex化:如何在React世界中享受Vue状态管理的优雅与强大"
【8月更文挑战第21天】在现代前端开发中,状态管理至关重要。Vuex作为Vue.js的状态管理库,通过集中式存储和严格规则确保状态变更的追踪。Redux则以其在React生态中的可预测性和灵活性著称。两者都强调单一数据源、状态只读及使用纯函数变更状态。尽管API设计不同,理解Redux的核心概念——单一数据源(`store`)、状态只读与纯函数变更(`reducers`),并参考Vuex的`state`、`mutations`等,能帮助开发者快速掌握Redux,高效管理应用状态。
16 0
|
1月前
|
JavaScript 前端开发 安全
|
2月前
|
Web App开发 JavaScript 前端开发
react18【系列实用教程】搭建开发环境(2024版)Vite+React (官方推荐)(含@配置,react-developer-tools 和 Redux DevTools 下载安装)
react18【系列实用教程】搭建开发环境(2024版)Vite+React (官方推荐)(含@配置,react-developer-tools 和 Redux DevTools 下载安装)
195 0
|
4月前
|
存储 JavaScript 前端开发
基于React和Redux的待办事项列表应用
基于React和Redux的待办事项列表应用
52 0
|
4月前
|
JavaScript 前端开发 搜索推荐
构建一个基于React和Redux的简易电商购物车应用
构建一个基于React和Redux的简易电商购物车应用
55 0

热门文章

最新文章