代码之家  ›  专栏  ›  技术社区  ›  Anand

Angular 6应用程序中的Host React组件

  •  2
  • Anand  · 技术社区  · 6 年前

    我正在尝试以角度6渲染React组件。 React组件来自tic-tac-toe教程 https://reactjs.org/tutorial/tutorial.html#setup-option-2-local-development-environment

    在提到React组件之前,我的角度组件(将作为主机)工作正常,并打印默认文本 component works

    我修改了组件和html文件,如下所示:

    <div>
      <div>
        <app-react-host-demo></app-react-host-demo>
      </div>
      <div id="demo-host"></div>
    </div>
    
    
    
    
    import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
    import {Square} from '../../../../../my-app/src/index.js';
    @Component({
      selector: 'app-react-host-demo',
      templateUrl: './react-host-demo.component.html',
      styleUrls: ['./react-host-demo.component.scss']
    })
    export class ReactHostDemoComponent implements OnInit {
    
      @ViewChild('demo-host')
      demoHost: ElementRef;
    
      constructor() { }
    
      ngOnInit() {
      }  
    }
    

    我犯了个错误 ERROR Error: Uncaught (in promise): RangeError: Maximum call stack size exceeded

    有人能告诉我怎么做吗?

    0 回复  |  直到 6 年前
        1
  •  0
  •   Jacquers    3 年前

    安装React软件包:

    npm i——保存dom npm i-D@types/react@types/react dom

    添加/更新tsconfig。json:

    “jsx”:“反应”, “allowSyntheticDefaultImports”:真 “严格”:false//可选

    这个例子帮助很大:

    https://github.com/zackypick/react-in-angular

    承载React组件的角度组件示例:

    import { AfterViewInit, Component, ElementRef, Input, OnChanges, OnDestroy, SimpleChanges } from '@angular/core';
    import { testPlatformProvider, Button } from '@test/test-ui-react';
    import { ButtonSize, ButtonVariant } from '@test/test-ui-react/dist/types/components/Button/Button.types';
    import React from 'react';
    import ReactDOM from 'react-dom';
    
    @Component({
        selector: 'app-test-button',
        template: ''
    })
    export class testButtonComponent implements AfterViewInit, OnChanges, OnDestroy {
        //https://react.ui.test/?path=/story/components-buttons-overview--page
        @Input() text = '';
        @Input() variant = 'primary';
        @Input() size = 'small';
        @Input() disabled: boolean;
    
        ElementToShow = () => (
            <testPlatformProvider>
                <Button variant={this.variant as ButtonVariant} size={this.size as ButtonSize} disabled={this.disabled}>
                    {this.text}
                </Button>
            </testPlatformProvider>
        );
    
        constructor(private hostRef: ElementRef) { }
    
        ngOnChanges(changes: SimpleChanges): void {
            //console.log('ngOnChanges: ' + this.hostRef.nativeElement);
            this.render();
        }
    
        ngAfterViewInit() {
            //console.log('ngAfterViewInit');
            this.render();
        }
    
        ngOnDestroy() {
            //console.log('ngOnDestroy');
            ReactDOM.unmountComponentAtNode(this.hostRef.nativeElement);
        }
    
        private render() {
            ReactDOM.render(<this.ElementToShow />, this.hostRef.nativeElement);
        }
    }
    

    另一个例子:

    import { AfterViewInit, Component, ElementRef, EventEmitter, Input, OnChanges, OnDestroy, Output, SimpleChanges } from '@angular/core';
    import { testPlatformProvider, Select } from '@test/test-ui-react';
    import React from 'react';
    import ReactDOM from 'react-dom';
    
    @Component({
        selector: 'app-test-select',
        template: ''
    })
    export class testSelectComponent implements AfterViewInit, OnChanges, OnDestroy {
        //https://react.ui.test/?path=/story/components-select-overview--page
        @Input() inputId = '';
        @Input() label = '';
        @Input() value: any;
        @Input() options: any[];
        @Input() isRequired = 'false';
        @Output() valueChange = new EventEmitter<string>();
    
        ElementToShow = () => (
            <testPlatformProvider>
                <Select
                    inputId={this.inputId}
                    label={this.label}
                    required={this.isRequired == 'true'}
                    value={this.value}
                    onChange={this.handleChange}>
                    {this.options && this.options.map((option: any) =>
                        <option key={option.value} value={option.value}>{option.label}</option>
                    )}
                </Select>
            </testPlatformProvider>
        );
    
        constructor(private hostRef: ElementRef) {
            this.handleChange = this.handleChange.bind(this);
        }
    
        ngOnChanges(changes: SimpleChanges): void {
            //console.log('select ngOnChanges: ' + this.hostRef.nativeElement);
            this.render();
        }
    
        ngAfterViewInit(): void {
            //console.log('ngAfterViewInit');
            this.render();
        }
    
        ngOnDestroy(): void {
            //console.log('ngOnDestroy');
            ReactDOM.unmountComponentAtNode(this.hostRef.nativeElement);
        }
    
        private render() {
            //console.log('select rendering');
            ReactDOM.render(<this.ElementToShow />, this.hostRef.nativeElement);
        }
    
        public handleChange(event: any): void {
            this.value = event.target.value;
            //console.log('select handleChange: ' + this.value);
            this.valueChange.emit(this.value);
            this.render();
        }
    }