React Component を wrap する Angular component を作成する
2021/05/08
はじめに
UIだけでもReactで書いておけばNext.jsに移行するとき楽なんじゃないかなという妄想から始めた。 Angularライブラリの恩恵を受けつつReactを使えるのでわりといい気がする。
AngularCompoentでReactをwrapする
プロジェクトにReactを追加する。
npm install --save react react-dom
npm install --save-dev @types/react @types/react-dom
# お好みで
npm install --save styled-components
npm install --save-dev @types/styled-components
moduleとcomponentを作成する。
npx ng g module ui/react-wrapper
npx ng g component ui/react-wrapper/react-wrapper
module
の export
でcomponentがimport先で使えるように設定する
@NgModule({
...
exports: [
ReactWrapperComponent
],
})
export class ReactWrapperModule { }
一旦 state
と prop
を忘れてとりあえずレンダリングされるwrapper compoentを実装する。
import { Component, OnInit, AfterViewInit, OnDestroy, Input, ElementRef } from '@angular/core';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
@Component({
selector: 'react-wrapper',
template: ''
})
export class ReactWrapperComponent implements OnInit, AfterViewInit, OnDestroy {
@Input() reactCompoent:React.Component | any;
constructor(
private elementRef:ElementRef
) { }
ngOnInit(): void {
}
ngAfterViewInit(): void {
ReactDOM.render(
React.createElement(this.reactCompoent),
this.elementRef.nativeElement
)
}
ngOnDestroy(): void {
ReactDOM.unmountComponentAtNode(
this.elementRef.nativeElement
);
}
}
使用例
npx ng g module ui/react-card
npx ng g component ui/react-card/react-card
mkdir src/app/ui/react-card/reaat-item
touch src/app/ui/react-card/reaat-item/react-card.tsx
*.tsx
ファイルを import
できるように tsconfig.app.json
を変更。
{
...
"include": [
"src/**/*.d.ts"
"src/**/*.tsx"
],
...
}
tsconfig.json
に以下を追加。
{
...
"compilerOptions": {
"jsx": "react",
}
...
}
react-card.module
で先程作成したWrapper Componentをimportする。
import { ReactWrapperModule } from '../react-wrapper/react-wrapper.module'
@NgModule({
...
imports: [
...
ReactWrapperModule
],
...
exports: [
ReactCardComponent
],
})
export class ReactCardModule { }
適当にReact Componentを作成。
import * as React from 'react';
import styled from 'styled-components';
type prop = {}
const Wrapper = styled.div`
padding: var(--size-itemInnerPadding);
background-color: var(--color-Main);
border: 3px solid var(--color-Paragraph);
border-radius: var(--size-cardBorder);
`
export const RCComponent:React.FC<prop> = prop => {
return (
<Wrapper>
sample text.
</Wrapper>
);
}
compoent側でtsxを読み込み、Wrapper Componentに渡す。
<react-wrapper
[reactCompoent]="reactCompoent"
>
</react-wrapper>
import { RCComponent } from '../reaat-item/react-card';
@Component({
selector: 'react-card',
templateUrl: './react-card.component.html',
styleUrls: ['./react-card.component.scss']
})
export class ReactCardComponent implements OnInit {
reactCompoent = RCComponent;
...
}
所感
- ui コンポーネントをReactで書くことができるので柔軟な開発環境を構築できるのではないかと
ここまでやるならAngularですべて完結したほうが良い
prop
とstate
対応をそのうちする。- 当ブログで使用してるComponentをとりあえずReactに置き換えてみる。