使用react-redux Provider for Angular 2 +中的React组件

时间:2017-10-11 20:31:54

标签: angular reactjs react-redux

我正在使用Angular 2+创建网站,但我还想使用某些React组件的库。那不应该那么难;但是,问题是这些组件需要react-redux Provider在根级别使用Redux存储才能工作。基本上文档树应该如下所示:

<body>
  ...
  <Provider store={store}>
    <span>
       <app-contents></app-contents>
       <TopLevelComponent/>
    </span>
  </Provider>
  ...
</body>

...其中<app-contents>是一个包含大部分网站内容的Angular组件,其中包含各种React组件的用法;和TopLevelComponent是另一个。

首先,我尝试使用@ngui/react来呈现React组件。这似乎可以用于小组件,虽然他们(正确地)抱怨无法访问商店。但是当用于提供者时,如下所示:

@Component({
  selector: 'app-provider',
  template: `
    <ngui-react [reactComponent]="provider" [reactProps]="{store: theStore}">
      <span>
        <app-provider-contents></app-provider-contents>
        <ngui-react [reactComponent]="topLevelComponent"></ngui-react>
      </span>
    </ngui-react>`
})
export class ProviderComponent {

  provider = Provider;
  topLevelComponent = TopLevelComponent;

  constructor(@Inject(TheStore) public theStore: Redux.Store<any>) {}
}

......导致错误:

Warning: Failed prop type: Invalid prop `children` of type `array` supplied to `Provider`, expected a single ReactElement.
    in Provider

ERROR Error: React.Children.only expected to receive a single React element child.

在我看来,原因可能是@ ngui / react过时了,所以我尝试在代码中动态创建Provider:

  constructor(@Inject(TheStore) private theStore: Redux.Store<any>,
              private elementRef: ElementRef) {}

  ngAfterViewInit() {
    const contents = React.createElement('app-contents', {key: this.randomKey}, null);
    const provider = React.createElement(Provider, {store: this.theStore, key: this.randomKey}, contents);
    ReactDOM.render(provider, this.elementRef.nativeElement, () => {});
  }

  get randomKey() { /* returns a pseudorandom string */ }

这导致:

<app-provider _ngcontent-c0="" _nghost-c1="">
   <app-contents></app-contents>
</app-provider>

...但<app-contents>未作为Angular组件加载,并且保持为空。

最后,我尝试使用这种情况并动态加载Angular组件。似乎有很多解决方案,但许多要求父元素通过各种指令,@ ViewChild和诸如此类的静态存在。然后,当我找到可以在给定DOM元素下插入的解决方案时:

const factory = this.factoryResolver.resolveComponentFactory(ProviderContentComponent);
const node = this.viewContainerRef.element.nativeElement.lastChild;
const component = factory.create(this.viewContainerRef.parentInjector, [], node);
this.viewContainerRef.insert(component.hostView);

...它呈现组件,但它将节点弹出到更高级别,并且其中的React组件再次抱怨无法访问商店:

<app-provider _ngcontent-c0="" _nghost-c1=""></app-provider>
<app-content _nghost-c2="" ng-version="4.4.4">
  content works!
  <!-- react component missing the store -->
</app-content>

所以,现在我想知道,实际上是否可以从Angular上下文,React Provider,Angular上下文切换到React组件,以便它可以工作?或者我是否必须摆脱React库并在Angular中本地生成组件?

0 个答案:

没有答案