ngx-react
v2.0.4
Published
Migrating from π °οΈ to βοΈ ? π Use React components in Angular, and vice versa
Readme
π§βπ» Sample
Jump to the sample repository for a a working sample (here on Stackblitz)
π Setup
1) Prepare your Angular project
A) Install ngx-react:
npm i ngx-reactB) Install React:
npm i react react-dom -S
npm i @types/react @types/react-dom -DC) Configure typescript so it picks up TSX:
"jsx": "react-jsx",(in your tsconfig.json, under the "compilerOptions" section)
D) Add the node_modules/ngx-react/src/* as included in your tsconfig.json compilation:
"include": [
"src", // you should already have this one if you had an "include" section :)
"node_modules/ngx-react/src/*" // π add this
// [...]
],(NB: If someone has a better solution that this, please tell me... but pre-compilling & publish the source seems to fail the angular build when installing this lib)
2) Declare your bridge
At the root of you project, declare a file bridge.ts :
import { NgxReactBridge } from "ngx-react";
// declare the bridge
export const reactBridge = new NgxReactBridge();you can OPTINALLY declare there the directives that will be available in your react componetns globaly, such as, for instance:
export const reactBridge = new NgxReactBridge();
.addDirective('focus', (focus: boolean, _, elt) => setTimeout(() => focus && elt.focus()))3) Enjoy
You can now use React & Angular together π₯³
Use π °οΈ Angular components in βοΈ React
Suppose you have an Angular component MyAngularComponent you would like to use in React.
In your component declaration file, just put:
import { reactBridge } from "./bridge";
// [...] MyAngularComponent declaration
// this will be usable in React:
export const MyAngular = reactBridge.toReact(MyAngularComponent, {
// declares that this component accepts children
children: true,
});Then, you'll be able to use this in react:
import {MyAngular} from './my-angular.component';
// use the component, enjoy the types !
const Other = () => <MyAngular input={'whatever'}>;Use βοΈ React components in π °οΈ Angular
Suppose you have a React component MyReactComponent you would like to use in Angular.
In your component declaration file, just put:
import { reactBridge } from "./bridge";
function MyReactComponent(props: {
data: string;
dataChange: (evt: string) => void;
}) {
// [...]
}
@Directive({ selector: "my-react-component" })
export class MyReactComponent_Angular extends reactBridge.toAngular(
MyReactComponent
) {
// a bit of extra work: You will have to map the properties yourself (type compatibility will be ensured by Tyepscript, though)
@Input()
data!: string;
@Output()
dataChange = new EventEmitter();
}Then, declare MyReactComponent_Angular in your ng-module, and you'll be able to use your component in Angular :
<my-react-component [(data)]="whatever"></my-react-component>You can also use content projection of Angular in your React component, by using the children prop:
function Thing(props: {
children: React.ReactNode;
}) {
// [...]
}
@Directive({ selector: "thing" })
export class ThingNg extends reactBridge.toAngular(Thing) {
}
// and use it like that in your angular template:
<thing>
<span> whatever </span>
</thing>Access π °οΈ Angular services from βοΈ React
Easy
function MyReactComp() {
const service = useService(SomeAngularService); // simple, isnt it ?
}
π °οΈ Angular outputs handling
Angular outputs are bound to callback props in react.
Meaning that:
@Ouptut() valueChange: EventEmitter<string>;Will be bound to a react prop:
valueChange: (evt: string) => any;@Input / @Outputs π °οΈ vs βοΈ React state hooks
When importing an Angular component in React, if your angular component has a matching @Input() and @Output() property pairs, say a value input, and valueChange output, you will notice that ngx-react will add a value$ property (name of the input, with a $ suffix) to the corresponding react type.
This property will be typed as something which is compatible with the useState() react hook. Meaning that, for if you have:
@Input() value: string;
@Ouptut() valueChange: EventEmitter<string>;Then you will be able to use your component in react like that:
const value = useState("");
return <MyComonent value$={value} />;... and the value state will be two-way bound with your react component !
(But of course, you can still use the value: string and valueChange: (e: string) => any props that ngx-react will have generated for you, if you prefer so)
π₯ TODO / Limits
Currently not supported (todo):
- Integration with the Angular router
