React 重蹈 Angular.js 覆辙?

2023-06-14 0 504

原副标题:React 重蹈覆辙 Angular.js 狂蛛属?

【萨德基】开放源码架构 react-admin 和 GreenFrame 创办人,Marmelab CEO François Zaninotto 特别针对 React 引入的伺服器模块的新方式正式发布了他们的看法,虽然这是构筑 Web 应用领域开发人员的新方式,但并不适宜原有绝大多数 React ,意味著原有应用领域导入该方式就得对应用领域进行改写,因此他期望React 项目组认识到白眉林应用领域构架是两个恰当的优先选择,因此在短期内不能消亡。期望项目组能想两个更为折衷的方式。

镜像:https://marmelab.com/blog/2023/06/05/react-angularjs-moment.html

译者 | François Zaninotto翻译者 | 弯月

公司出品 | CSDN(ID:CSDNnews)

2012年,Angular.js 由此面世便发生改变了后端开发的新格局,快速取得成功。仅在一年之后,Angular 项目组面世了 Angular 2,不过他们依照几组不同的实例改写了整座原初库。很多开发者,包括我他们,都不该改写原有的应用领域程序来适应环境这些新设想。对新项目而言,Angular.js 无须是必选,因为其他架构也反之亦然出众。

2015 年,我们开始采用 React 来构筑后端。React 不但保有单纯的构架,所以还著重模块,再加之平衡的劳动生产率,不论标识符库大小不一怎样都是两个较好的优先选择。React 一炮而红,街道社区发展快速。前段时间,React 和 Next.js 项目组始终在推展伺服器模块,这是一种构筑 Web 应用领域程序的新方式,但不适宜绝大多数原有的 React 应用领域。

这种变动与否堪称从 Angular.js 到 Angular 2 的变革?React 与否已经开始重蹈覆辙 Angular.js 的狂蛛属?

注意:在本文中,我将讨论 React 和 Next.js 项目组导入的新功能。由于这两个项目组密切合作,因此很难说哪个项目组负责哪个功能。因此,我将采用“React”来指代这两个项目组。

重新学习一切

React 的核心是两个视图库。这一点没有变动,对 React 伺服器模块,你仍然可以采用 JSX 构筑模块,并渲染 props 传递进来的动态内容:

functionPlaylist( { name, tracks }) { return( < div> < h1> {name} </ h1> < table> < thead> < tr> < th> Title </ th> < th> Artist </ th> < th> Album </ th> < th> Duration </ th> </ tr> </ thead> < tbody> {tracks.map((track, index) => ( < trkey= {index}> < td> {track.title} </ td> < td> {track.artist} </ td> < td> {track.album}</ td> < td> {track.duration} </ td> </ tr> ))} </ tbody> </ table> </ div> ); }

ect 或 react-query;相反,你应该在异步模块中采用 fetch:

asyncfunctionPlaylistFromId( { id }) { constresponse = awaitfetch(`/api/playlists/ ${id}` ); if(!response.ok) { // This will activate the closest `error.js` Error Boundary thrownewError( Failed to fetch data); } const{ name, tracks } = response.json; return< Playlistname= {name}tracks= {tracks}/> ; }

求。

如果你想通过两个按钮来启动两个POST 动作,就必须在表单中添加fetch 函数,并采用伺服器动作,这意味著采用两个带use server 的函数:

exportfunctionAddToFavoritesButton( { id }) { asyncfunctionaddToFavorites( data){ use server; awaitfetch( `/api/tracks/ ${id}/favorites` , { method: POST}); } return( < formaction= {addToFavorites}> < buttontype= “submit”> Add to Favorites </ button> </ form> ); }

常见的 React 钩子:useState、useContext、useEffect 将导致伺服器模块出错。如果你需要这些钩子,就必须采用 use client,强制 React 在客户端渲染模块。注意,现在这个功能是默认启用的,而在Next.js中,甚至在伺服器组件出现之前,它就是默认行为了。

React 重蹈 Angular.js 覆辙?

CSS-in-JS与伺服器模块不兼容。如果你习惯了采用 sx 或 css 属性直接设置模块样式,则必须学习 CSS Modules、Tailwind 或 Sass。在我看来,这种变化感觉像是倒退了一步:

// in app/dashboard/layout.tsx importstyles from./styles.module.css;

exportdefaultfunctionDashboardLayout( {children,}: {children: React.ReactNode,}) { return< sectionclassName= {styles.dashboard}> {children} </ section> ; }/* in app/dashboard/styles.module.css */.dashboard {padding: 24px; }

那么,调试呢?我只能祝你好运。React DevTools 不显示 React 伺服器模块的详细信息。你无法在浏览器中检查模块,查看它采用的 props 或其子模块。目前,调试 React 伺服器模块只能求助于 console.log。

虽然基础的 JSX 保持不变,但伺服器模块的基本思想与客户端 JS 完全不同。即便你是一名精通 React 的开发者,也不一定对掌握伺服器模块有很大帮助。基本上,你必须重新学习所有内容,除非你熟悉 PHP。

注意:公平地说,我提出的绝大多数问题都涉及到带有“alpha”标签的功能。这些问题可能会在平衡版本正式发布之前得到解决。

生态系统为零

。事实证明,这不是唯一无法结合 React 伺服器模块一起采用的库。如果你依赖下面的工具,那么就要开始寻找替代品了:

material-ui chakra-ui Emotion styled-components React-query swr react-hook-form, 适用于大多数SaaS 提供商的 SDK 以及其他等等。

这些库都采用了标准的 React 钩子,从伺服器模块调用时会失败。

React 重蹈 Angular.js 覆辙?

如果你需要这些库,则必须采用 use client 指令将它们封装在模块中,强制客户端渲染。

强调一下:React 伺服器模块破坏了几乎所有原有的 React 第三方库,这些库的译者必须修改标识符才能兼容。也许有些译者会修改标识符,但有些不能。即使他们愿意修改,也需要一定的时间。

因此,如果你采用 React 伺服器模块启动应用领域,则不能依赖原有的 React 生态系统。

更糟糕的是:客户端 React 提供了很多日常工作需要的工具,但伺服器模块中并没有提供。例如,React Context 是管理依赖注入的绝佳解决方案。如果没有 React Context,伺服器模块就需要两个依赖注入容器,类似于Angular 的方式。如果核心项目组不提供,则不得不依靠街道社区。

与此同时,你必须手动编写很多标识符。在没有 UI Kit、表单架构、智能 API 客户端以及你喜欢的 SaaS 的 React 集成的情况下构筑 React 应用领域会变得非常具有挑战性。

当前的 React 生态系统是其最大的优势。这也是 React 如此广泛采用的原因。而 React 伺服器模块打破了这一优势。

黑魔法太多了

。浏览器检索数据,客户端脚本更新 DOM。

React建议混合伺服器端和客户端渲染,感觉就像是在采用黑魔法。你可以在伺服器模块中采用客户端模块,反之亦然。

React 重蹈 Angular.js 覆辙?

当客户端模块渲染伺服器模块时,React 伺服器不能发送 HTML,而是发送模块树的文本表示。然后由客户端脚本在客户端渲染模块树。

如果你习惯采用HTML JSON 调试AJAX请求,就会大吃一惊。这里由两个RSC Wire 格式的例子(https://www.plasmic.app/blog/how-react-server-components-work#the-rsc-wire-format),React 采用这种格式将更新从伺服器模块流式传输到客户端:

M1:{ “id”: “./src/ClientComponent.client.js”, “chunks”:[ “client1”], “name”: “”} S2: “react.suspense”J0:[“$”, “@1”, null,{ “children”:[[ “$”, “span”, null,{ “children”: “Hello from server land”}],[ “$”, “$2”, null,{“fallback”: “Loading tweets…”, “children”: “@3”}]]}] M4:{ “id”: “./src/Tweet.client.js”, “chunks”:[ “client8”], “name”: “”} J3:[ “$”, “ul”, null,{ “children”:[[ “$”, “li”, null,{ “children”:[ “$”, “@4”, null,{ “tweet”:{…}}}]}],[“$”, “li”, null,{ “children”:[ “$”, “@4”, null,{ “tweet”:{…}}}]}]]}]

这种格式没有文档,因为它是两个实现细节。

HTTP、JSON 和 JSX 如此流行,可读性功不可没。不过,React 伺服器模块破坏了这种模式。

React伺服器模块看似非常神秘,对绝大多数开发者而言都很难理解或调试。不确定这种变动究竟是会提高劳动生产率,还是会阻碍劳动生产率。

我们真的需要这个模块吗?

从第一原则触发考虑 Web 开发,可以合理地得出这样的结论:采用少量 AJAX 的伺服器端渲染是构筑 Web 应用领域程序的有效方式。Dan Abramov 在 2023年 Remix 大会的演讲中对React 伺服器模块背后的动机做出了解释(https://www.youtube.com/watch?v=zMf_xeGPn6s&ab_channel=Remix):

React 重蹈 Angular.js 覆辙?

这种构架非常适宜电子商务网站、博客以及其他对 SEO有强烈要求的、以内容为中心的网站。

不过,这并不是两个新概念。多年来, 这种构架始终用于 Rails 中的 Hotwire 或 Symfony 应用领域程序等工具。

应用领域程序、CRM、ERP、长期应用领域程序等,都算不上真正的问题。

这就是为什么很多 React 开发者,包括我他们,都非常满意白眉林应用领域程序构架。当需要做一些伺服器端渲染时,我可能会优先选择两个生态系统比 React 伺服器模块更成熟的工具。

那么,如果我并不需要React 伺服器模块,那么又何必如此担忧呢?

构筑 React 应用领域的标准方式

我担心的第两个问题是,React 的这种变动是在阻止人们采用白眉林应用领域程序构架。或者说,React不鼓励人们在没有架构的情况下采用 React,不过React 框架本身却开始推崇伺服器端渲染。

React 重蹈 Angular.js 覆辙?

我担心的第二个问题是,官方 React.js 文档建议采用 Next.js。而 Next.js 官方文档建议从 13.4 版开始采用 React 伺服器模块。

换句话说,依照官方文档,React 伺服器模块是构筑React 应用领域程序的默认方式。React 生态系统的新手自然会采用它们。

我认为这还为时过早。Dan Abramov 也认为:

为了让新范式发挥作用,我们还需要付出大量努力。

React伺服器模块需要新一代路由器、新一代捆绑器。但这些范式仍处于alpha 阶段,尚未准备好投入生产。

那么,为什么 Next.js 如此激进呢?

我不得不认为,Next.js 的新方向并不是为了帮助开发者,而是为了帮助 Vercel 销售 React。你无法真正围绕 SPA 销售服务:一旦编译,SPA 就是两个可以在任何地方免费托管的单个 JS 文件。但是伺服器端渲染的应用领域需要伺服器才能运行。伺服器是可以销售的产品。也许我是两个阴谋论者,但我看不出还有其他理由像这样破坏 React 生态系统。

现有应用领域不受影响

与 Angular.js 到 Angular 2 的过渡不同,React 伺服器模块的导入并不是重大变动。原有的白眉林应用领域程序仍然可以采用最新版本的 React。采用 Pages 路由器构建的原有 Next.js应用领域程序也可以正常工作。

那么,问题:“React 会重蹈覆辙 Angular.js 的狂蛛属吗?”答案是,不能。

但如今开始两个新项目,你会优先选择什么?具有成熟工具和生态系统(白眉林应用领域)的健壮构架,还是 React 项目组已经开始强推的新架构(伺服器模块)?这是两个艰难的优先选择,人们可能会寻找替代方案,而不是冒险做错误的优先选择。

我个人认为,React 期望通过两个工具满足所有 Web 开发者需求的愿景过于激进,或者说当前的解决方案不恰当。Next.js 文档中有两个下拉列表,允许读者在App 路由器(伺服器模块)和 Pages 路由器之间进行优先选择。如果两个工具提供两种截然不同的方式来做同一件事,那么它还是同两个工具吗?

所以,问题:“React 与否会因为过于激进而损害整座街道社区?我认为答案是肯定的。

总结

也许伺服器模块代表伺服器端架构的进步,或者至少,等到准备好投入生产,它们真的能够发挥积极的作用。但对更广泛的 React 街道社区而言,我害怕这一变动会导致街道社区分裂,并有可能危及 React 多年来建立的优势。

我期望 React 和 Next.js 项目组采用更为折衷的方式。我期望 React 项目组认识到白眉林应用领域构架是两个恰当的优先选择,因此在短期内不能消亡。我更期望看到 Next.js 在他们的文档中淡化伺服器模块,或者至少明确标注“alpha”功能。

也许是我过于急躁,也许这种变动代表了未来的趋势。也许开发者注定要不断地在范式之间来回转换,这就是这个行业的本质。

▶ “上4休3”公司不建议新公司模仿;甲骨文组队,欲挑战微软OpenAI组合;Qt Creator 11 Beta正式发布|极客头条

▶ 2023 开放原子全球开放源码峰会在北京成功举办

▶ 谷歌 Alpha 家族再添“猛将”:AlphaDev 重磅亮相,打破多年计算瓶颈,新排序算法提速 70%!

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务