如何在Angular包装的React组件中访问公共属性userName$
在Angular包装器中传递用户名到嵌套React组件
问题场景
现有AngularJS应用需新增React开发的功能,React组件嵌套在Angular包装器内。已在Angular中通过sessionService获取到当前用户信息并成功打印,但无法在React组件中访问该用户名。
Angular包装器代码
import { HttpClient } from '@angular/common/http'; import { AfterViewInit, Component, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core'; import { DomSanitizer } from '@angular/platform-browser'; import { Select } from '@ngxs/store'; import { SessionService } from 'AngularApplication-client'; import { combineLatest, Observable, of } from 'rxjs'; import { catchError, map, shareReplay, startWith } from 'rxjs/operators'; import { UserState } from '../../../auth/state/user.state'; import * as React from 'react'; import {createRoot} from 'react-dom/client'; import MaintainWrapper from './maintain.wrapper'; @Component({ selector: 'app-maintain', template: '<div [id]="pageId"></div>', }) export class MaintainPage implements AfterViewInit, OnChanges, OnDestroy, OnInit { public developerInfo = environment.developerInfo; public developerDebug = environment.developerDebug; public developerTemplateDebug = environment.developerTemplateDebug; @Select(UserState.isLoggedIn) public isLoggedIn$: Observable<boolean>; public dataSource$: Observable<Array<StatusTableRow>>; public userName$: string; public pageId = 'maintainPage'; public ngOnChanges(changes: SimpleChanges){ this.render(); } public ngAfterViewInit(): void { this.render(); } public ngOnDestroy(): void { } constructor( private readonly httpClient: HttpClient, private readonly sessionService: SessionService, ) {} public ngOnInit(): void { this.dataSource$ = combineLatest([ this.getApiStatus() ]).pipe( shareReplay(1) ); // 获取当前登录用户 this.sessionService.getMySessionUsingGET().subscribe(data => { if (this.developerDebug){ console.log("?Name?: ", data.account.name); } this.userName$ = data.account.name; }, error => { console.log(error); }); } private getApiStatus(): Observable<StatusTableRow> { return this.httpClient.get('/AngularApplication', { observe: 'response' }).pipe( map(response => ({ name: 'API', status: response.status })), startWith({ name: 'API', status: 0 }) ); } private render(){ const root = createRoot(document.getElementById(this.pageId) as HTMLElement); root.render( React.createElement(MaintainWrapper) ); } }
React组件问题代码
import * as React from 'react'; import { SessionService } from 'AngularApplication-client'; function ReactComponent() { const User1 = UserState.username; const User2 = SessionService; console.log('Username: ', User1); console.log('Username: ', User2); return ( <h1> Hello {User1}</h1> ); } export default ReactComponent;
解决方案
1. 在Angular中传递用户名到React组件
修改Angular组件的render方法,将userName$作为props传递给React组件:
private render(){ const root = createRoot(document.getElementById(this.pageId) as HTMLElement); // 传递userName作为props参数 root.render( React.createElement(MaintainWrapper, { userName: this.userName$ }) ); }
2. 在React组件中接收并使用用户名
修改React组件,通过函数参数接收props,直接使用传递过来的用户名:
import * as React from 'react'; function ReactComponent(props) { const userName = props.userName; console.log('Username: ', userName); return ( <h1> Hello {userName}</h1> ); } export default ReactComponent;
3. 处理异步加载的边界情况
由于用户名是通过异步请求获取的,初始值可能为undefined,可以通过以下方式优化:
方式一:Angular中确保数据加载后再渲染
在用户信息请求的回调中调用render,避免React组件初始渲染时无数据:
this.sessionService.getMySessionUsingGET().subscribe(data => { if (this.developerDebug){ console.log("?Name?: ", data.account.name); } this.userName$ = data.account.name; // 获取到用户名后再渲染React组件 this.render(); }, error => { console.log(error); });
方式二:React中添加加载状态
在React组件中判断用户名是否存在,显示加载提示:
function ReactComponent(props) { const userName = props.userName; if (!userName) { return <h1>Loading...</h1>; } return ( <h1> Hello {userName}</h1> ); }
内容的提问来源于stack exchange,提问作者Mtullis
相关产品推荐
相关产品推荐

