我知道 ReactJS 不被认为是 MVC,因为创建者自己是这么说的。但是,最近,有人问我为什么 React 不被认为是 MVC,即使它符合 MVC 模式。React 渲染一个视图,当使用客户端的人进行更改时,React 将考虑更改,如果需要更新状态(状态不只是模型?),然后返回更新的视图(就像控制器一样将)。我对 MVC 架构的严格定义有一个非常基本的了解,并且对为什么 React 现在不是 MVC 感到非常困惑。
为什么 React 不被认为是 MVC?
React 既不是 MVC 也不是 MVC。这是一个渲染视图的库(有很多很酷的东西,但仍然如此)。您可以使用 MVC 模式或 Flux/Redux 或其他任何模式。
MVC 和 Flux 的区别在于,最新实现了单向数据流。因此,您的数据只能向一个方向移动。Action -> Middleware -> Store -> View
. MVC 是双向的;您可以从视图和控制器更改模型。
React 不被视为 MVC,因为它与 MVC 在后端的构思和使用方式并没有很好地对应。React 是一个渲染库,理想情况下只负责视图层。它没有中央控制器作为协调器/路由器,因为后端的 MVC 架构通常已经具备。
也就是说,你可以说 React 在某种意义上实际上是 MVC(更接近 MVC 的原始含义)。
React 正在垂直(通过关注)切片 MVC,而不是水平(通过技术)切片,这是人们对 MVC 模式所做的。MVC 已经成为一种分层架构,视图作为顶部的一个薄层。(虽然最初并非如此*)。
你可以说 React 中的组件一开始是小的垂直切片封装的 MVC:包含状态(模型)、渲染(视图)和控制流逻辑(本地化的微型控制器)。
目前,组件(在 React 和 SolidJS 等前端库中)将渲染与渲染逻辑混合在一起。组件的范围从完全面向视图到完全面向控件。这会导致概念混乱。
但大多数组件介于两者之间;有一点渲染输出和控制流逻辑。
所以目前,React Components 更像是一个垂直切片的 ViewController,其中 Model 位包含在其他地方。例如在像集中式 Redux 这样的状态处理库中,或者在单独/正交的 Recoil 存储中。或者只是伪包含在带有钩子的组件中useState
(而实际上由 React 包含)。
因此,组件目前可以被视为 ViewControllers。
看到 React Components 与 iOS 的 UIViewControllers** 的相似性很有趣。也许这种来自 iOS 原生开发的心智模型影响了组件的创建,考虑到 Facebook 的 React + React Native 组合旨在拥有相同的框架和心智模型来处理纯原生和 Web。
'视图控制器 (VC) 管理视图并帮助制作应用程序的 UI。它与模型对象和其他控制器对象协调。它以同时扮演视图对象和控制器对象的角色而闻名。每个 VC 都显示自己的应用程序内容视图。- iOS ViewController 生命周期
如果您需要进一步的说服力,只需阅读Apple 的 Swift 中的 ViewControllers 文档,并想象他们在谈论 React 组件。几乎没有阻力(认知失调)。
更新:如今,随着大量组件逻辑被提取到 Hooks 中,您可以将组件更多地视为仅仅是视图,而将钩子视为控制器。正如ryanflorence和swizecteller所指出的那样。
* 有趣的是,前端编程 (React) 仍在努力实现 MVC,因为它最初是由 Trygve Reenskaug 在 1979 年提出的,他已经用 Smalltalk 实现了它。它被实现为将界面/屏幕切成无数个微小的原子/组件,每个原子/组件都遵循 MVC 模式:请参阅“屏幕上的每个小部件都有自己的模型、控制器和视图”。在MVC 不是架构。尽管这种方法有一些缺点,尤其是与同步状态更改有关,但正如这篇出色的可视化 MVC 解释器文章中以“有时 MVC 应用于单个小部件级别...”开头的部分所述. 在 React 中,同步状态是通过“props钻取”(这成为它自己的问题,由 Redux 或中央状态库解决)结合 Flux 架构的单向数据流来处理的。
** 应该注意的是,iOS ViewController - 就像后端 MVC 模式中的控制器 - 可能比控制器有更广泛的关注点(如跨组件通信,更少的封装),因为 React组件是一个 ViewController。由于 React 组件是 React 的 JSX/DOM 层次结构和 Flux 架构的一部分。关于“控制器”的实际含义,可能有几种不同的定义。但出于我的意图和目的,我将其视为控制流逻辑的中心(无论是用于简单的视图渲染,还是在后端情况下,也用于路由和模型编排)。
我觉得接受的答案有点不完整,所以只想添加三个要点(当使用flux/redux来说明答案时)。
从这里:https : //medium.com/createdd-notes/understanding-mvc-architecture-with-react-6cd38e91fefd
处理流程是单向的而不是双向的
store 能够存储任何与应用程序相关的状态,而 MVC 中的模型旨在存储单个对象
启动点 Dispatcher 使调试更容易