coatue-oss / react2angular

The easiest way to embed React components in Angular 1 apps.
Other
545 stars 109 forks source link

Is it possible to put AngularJS components inside your React component? #87

Open coreysnyder opened 6 years ago

coreysnyder commented 6 years ago

I've got a React component that is used in my AngularJS app using react2angular. When I try to put AngularJS components in my HTML/JSX, they don't get turned into the angular components they represent.

class ProjectListContainer extends React.Component {

  constructor(props) {
    super(props);
    this.state = {};
  }

  render() {
    return (
      <my-angular-component></my-angular-component>
    )
  }
}

// ########## ANGULAR ROUTE #############/
var angular = require('angular');
require('./project-list.less');
var uiScaffolding = require('@aver/ui-scaffolding');

module.exports = angular.module('aver.episode-workbench.projectListReact', [uiScaffolding])
.component('reactTestComponentAsPage', react2angular(ProjectListContainer, [], ['$state']))
.config(function($stateProvider) {

  var reactComponentAsPageState = {
    name: 'project-list-react',
    url: '/project-list-react',
    component: 'reactTestComponentAsPage',
  };
  $stateProvider.state(reactComponentAsPageState);
})
.name;

Is this supposed to work? I know the component is included in the source as it's part of the uiScaffolding library and I can see it in the compiled JS. Should this work?

Furthermore I tested a similar situation not using react2angular and it seems to work.

'use strict';

var angular = require('angular');
var templateUrl = require('./react-page.html');

import React from 'react';
import ReactDOM from 'react-dom';
import { Component } from 'react';

class MyComponent extends Component {
  render() {
    return (
      <div>
        <p>FooBar: {this.props.fooBar}</p>
        <p>Baz: {this.props.baz}</p>
        <privacy-policy></privacy-policy> <<--- THIS IS AN ANGULAR COMPONENT
      </div>
    )
  }
}

module.exports = angular.module('aver.episode-workbench.reactPage', [])
.config(function($stateProvider) {

  var reactPageState = {
    name: 'reactPage',
    url: '/react-page',
    controller: 'reactPageCtrl',
    controllerAs: 'reactPageCtrl',
    templateUrl: templateUrl,
    requiresPermission: 'view_episode_workbench'
  };
  $stateProvider.state(reactPageState);
})
.component('reactTestComponent', {
    restrict: 'E',
    template: ['$element', '$attrs', function($element, $attrs) {
      console.log('template func', $attrs);
      ReactDOM.render(
        <MyComponent fooBar={'corey'} baz={'snyder'}/>,
        $element[0]
      );

    }],
    scope: {
      data: '=theData'
    },
})

.controller('reactPageCtrl', function() {
  var vm = this;

  vm.$onInit = function() {
    console.log('reactPageCtrl init');
  };

})

.name;
ajdaniel commented 6 years ago

JSX is not html and is therefore, by default, not processed by angular. Putting Angular components in JSX is not designed to work. You would have to use a reverse library, something like angular2react (I've not looked to see if any such library exists).

I am not 100% sure why your second scenario works, but as it doesn't seem to be design, I don't think you should rely on that method as it could be taking advantage of a bug or unknown side-effect.

I would recommend finding a library to convert an Angular component to a React component and then putting that converted component into your JSX.

bcherny commented 6 years ago

Cough https://github.com/coatue-oss/angular2react

trisys3 commented 5 years ago

I have a similar use case with similarly baffling results, and I may have figured it out, though I'm not sure. reactTestComponent is in the aver.episode-workbench.reactPage component, and though you didn't say so, I'm going to assume privacyPolicy is, too, as it matches observations from my app. On the other hand, reactTestComponentAsPage is inside the aver.episode-workbench.projectListReact module, but you said that myAngularComponent is in the uiScaffolding library, which would be in another module.

@CoreySnider, am I correct in my assumptions?