在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正在广泛招募成员。

只要你想听听的话,你可以随意报名,我们欢迎!

美津濃采用页面:美津濃采用信息

广告
将在 10 秒后关闭
bannerAds