I’m migrating an existing React app over to Angular. Each React component will eventually be rewritten, but in the meantime I’m hosting them in Angular components based on this method: https://medium.com/@joseph5/rendering-react-component-in-angular-apps-9154fa3198d1. I’m using a component instead of a directive, but otherwise it’s the same.
This works fine, and I can render the React components in Angular. What I’d like to do is give them access to services provided in the Angular app. Most importantly, I want them to share the Angular app’s NGRX store. The existing components were using useDispatch
and useSelector
from the react-redux library, but since they’re now standalone components, there’s no app-level store provided for those to use. I have to provide access to my NGRX store, which can’t be injected into the React component because it’s not in an Angular injectionContext.
What I’ve been doing is injecting the store into the Angular host and passing it through the props:
// Angular
@Component({
selector: 'app-search-results',
template: `<ng-react [component]="SearchResults" [props]="props"></ng-react>`,
encapsulation: ViewEncapsulation.None,
styleUrl: './search-results.component.scss'
})
export class SearchResultsComponent {
SearchResults = SearchResults;
props = {
store: inject(Store),
};
}
And then in the React counterpart:
// React
const SearchResults = (props) => {
const store = props.store;
const [filterData, setFilterData] = useState(initialState);
// creates an observable once and subscribes to it with the given callback
useObservable(() => store.select((state) => state.filterData), setFilterData);
// ...
This works. The only problem with it is that sometimes these components have children and grandchildren that also need access to NGRX or some other Angular service. I’d prefer not to keep passing it down through the props. I’ve experimented with createContext
, but I can’t find a satisfying way to use it for this. Can anyone recommend the best way to share my NGRX store with these React components?
2
Answers
I believe you will have to pass to the input to every "react root" the injector, but at least the rest of things can be a bit better.
usage
Use RxJS for Cross-Framework Communication Expose Angular service data as an Observable.
Subscribe to the Observable from within the React component.
1. Modify Angular Service to Use RxJS
2. Subscribe to the Angular Service Data in React
3. Pass the Observable from Angular Service into React