在Angular上尝试使用React(从Angular迁移至React)
這篇文章是MICIN Advent Calendar 2022的第18天的文章。
上次是酒井先生的文章。
索引
-
- はじめに
-
- 前提として
-
- 実装の仕方
-
- 実装で詰まったポイント
- まとめ
首先
非常感谢大家,非常感谢大家。我是在线医疗平台curon的工程师影山,请大家多多关照~
嗯嗯,MICIN Advent Calendar 2022的上一篇是酒井先生的「期望更快、更高质量的产品开发:利用Confluence和Jira构建现代化开发流程」。如果还没看过的朋友,非常非常建议您一起阅读哦。
由于今天是第18天,我打算写一篇关于在Angular上使用React进行实现的文章。
请用中文将以下内容改述一遍,只需要提供一种选项:
Paraphrase the following natively in Chinese, only need one option.
首先
MICIN有许多不同的产品,并且每个产品都使用了各种不同的技术。但是,今天要介绍的产品是curon(在线医疗服务),它已经被实施到了MICIN创立时就存在的产品中。这是一款特别古老的产品,因此在技术上有很多古老的部分。
其中,特别增加了学习成本的是Angular和RxJS。在Curon中,使用Promise完全可以代替RxJS,且MICIN的前端实现基本上都是以React为主,只有这个产品使用了Angular。为了这个产品,我们不得不学习Angular作为全栈框架的写法和RxJS的Observable等技术,这对其他部门来说是很困难的,成为了负债。
就算是想在Curon中采用React,我们也必须考虑与现有产品和技术栈的整合。然而,由于我们的产品成立至今已有一段时间,且实现规模庞大,一下子彻底改变并不现实。
因此,經過一番考慮後,我們得出一種方法,即在Angular中進行React化,並逐漸地將每個組件轉換為React組件。
请将以下内容用中文进行翻译,只需要给出一个翻译选项:
“Can you please help me with this task?”
实施的方法
现在,我已经详细阐述了许多前提条件,但是我认为大家最关心的是如何实施。
用中文来概括一下,就是通过Angular创建一个div元素,并使用DOM操作将React组件输出到这个div中,接下来我将通过示例代码来解释。
作为整体结构的实现如下:
package.json 文件
"react": "^18.0.0",
"react-dom": "^18.0.0",
"@types/react": "^18.0.5",
"@types/react-dom": "^18.0.1",
//その他にもMUIなど使いたいReactのライブラリーを追加
请将以下内容用中文进行本地化改写,只需要一个选项:
“All progress takes place outside the comfort zone.”
Angular 组件。
import {
AfterViewInit,
Component
EventEmitter,
Input,
OnChanges,
OnDestroy,
Output,
} from '@angular/core'
import React from 'react'
import { createRoot, Root } from 'react-dom/client'
//表示したいReactのコンポーネントとそのコンポーネントのPropsをimport
import { Demo, Props } from './demo'
//styleThemeなど全体で統一したいもの
import { RootProvider } from '@app/react/helpers/RootProvider'
@Component({
selector: 'confirmation-modal-content-react-component',
template: '<div [id]="rootId"></div>',
})
export class ReactDemoComponent implements OnChanges, AfterViewInit, OnDestroy {
//一つの画面で同じReactコンポーネントを呼び出したい場合はこのIDをユニークにする必要があります
public rootId = 'demo-react-component'
private hasViewLoaded = false
private root: Root
//Angularの呼び出し部で指定した@Input,@Outputの呼び出し
@Output() hoge = new EventEmitter<void>()
@Input() value: Value
public ngOnChanges() {
this.renderComponent()
}
public ngOnDestroy() {
this.root.unmount()
}
public ngAfterViewInit() {
//divが表示される前にrenderComponentが流れると困るのでここで制御
this.hasViewLoaded = true
this.renderComponent()
}
private renderComponent() {
if (!this.hasViewLoaded) {
return
}
const props: Props = {
hoge: () => this.hoge(),
}
const container = document.getElementById(this.rootId)!
if (!this.root) {
this.root = createRoot(container)
}
this.root.render(
// App.tsxがないため全体に聞かせたいstyleThemeやcontextは全てRootProviderに定義する
React.createElement(RootProvider, {
//Reactのコンポーネントとpropsを指定する
children: React.createElement(Demo, props),
}),
)
}
}
在Angular中,可以通过编写类似的模板来调用React组件!
在React组件的一侧,您可以安心地创建组件,无需特别说明。
通过使用React.createElement,我们能够调用React是因为它们都是JS,所以才可以做到这一点!
请用中国语言进行原生的改述,只需要一个选项:
This is a beautiful day, and I want to go for a walk in the park.
实施过程中遇到的难点
我希望能够分享一些在实施过程中遇到的一些困难点,即使按照写的那样写,也可以基本上正常运行,但还是有一些地方会遇到问题。
没有App.tsx文件。
在使用create-react-app或next.js等工具进行开发时,我们需要在一个共享的地方写下适用于整个组件的代码,例如共享主题或Context的提供者等。但是由于需要为每个组件都进行React.createElement的操作,所以无法创建App.tsx文件。
在整体上指定主题时该如何处理呢?本次我们采用了通过嵌套createElement来为整体设定一个模板,并在所有组件中共同描述希望作为共通部分的内容。
// App.tsxがないため全体に聞かせたいstyleテーマやcontextは全てRootProviderに定義する
React.createElement(RootProvider, {
//Reactのコンポーネントとpropsを指定する
children: React.createElement(Demo, props),
}),
)
请用中文将以下内容表达成不同的句子:
有时候,在React中导航可能存在问题。
导航通常在Angular部分作为函数创建,并将其传递给React以进行页面跳转的操作。
在Angular之外发生事件时,如果不指定NgZone来检测更改,可能会出现无法转换的问题。
我在Angular导航位置做出了以下描述并进行了相应的处理。
this._ngZone.run(() => {
this.router.navigate(path, { queryParams, ...extras })
})
请用中文将以下内容进行释义:
在React组件之间共享全局值是困难的。
虽然在App.tsx中稍微提到了,但是由于每个组件都使用React.createRoot,无法共享上下文值,因此在组件之间共享数据变得困难。最初打算使用ReactQuery来进行与产品后端API的通信,但需要在App.tsx中拥有Provider,所以放弃了…
在进行调查的过程中,如果使用SWR,可以在没有Provider的情况下通过缓存很好地共享数据,因此我们基本上决定通过SWR来管理共同的值。
总结
嗯~我一直写这方面的时候并没有触及到Angular和React哪个更好之类的事情,但是使用React进行开发确实给我一种安心感。Angular和Rxjs在适当的使用场景下也能展现出强大的力量,但是只要能用React来实现,即使在与其他产品开发来回切换时也能有相同的便利,这对于开发体验来说非常好。
虽然很简单,但我介绍了从Angular调用React组件的方法,目前只有少数几个地方将产品转为React,但未来希望全部转为React。如果有进展或遇到难点,我也希望在文章中进行分享。
请以中文母语进行改写,只需提供一种选项:
请重新用中文表达以下内容:
参考自的文章
将React组件整合到Angular 2+项目中
请将以下内容用中文翻译一遍,只需要一种版本。
“Can you please help me with this task?”
MICIN正在广泛招募成员。
只要你想听听的话,你可以随意报名,我们欢迎!
美津濃采用页面:美津濃采用信息