我想在一个angularjs应用程序中完全重用一个小的react应用程序。有没有办法达到同样的效果。我已经使用ngReact在angular js中加载了react,它工作得很好。但是,我如何在不做太多更改的情况下完全重用应用程序。
注意:我知道这是一个糟糕的做法,但由于遗留代码,必须实现它。
任何线索都是值得感谢的。蒂娅!
发布于 2020-12-02 18:34:03
解决方案实施
package.json
"dependencies": {
...
"react": "^16.12.0",
"react-dom": "^16.12.0",
...
},
"devDependencies": {
...
"@types/react": "^16.9.17",
"@types/react-dom": "^16.9.4",
...
}tsconfig.json
{
...
"jsx": "react",
...
}包装器组件
包装器负责检测更改并重新呈现包装的React组件,以使其属性生效,最终在包装器被销毁时卸载包装的组件。
MyReactComponentWrapper.tsx
import {
AfterViewInit,
Component,
ElementRef,
EventEmitter,
Input,
OnChanges,
OnDestroy,
Output,
SimpleChanges,
ViewChild,
ViewEncapsulation
} from '@angular/core';
import { MyReactComponent } from 'src/components/my-react-component/MyReactComponent';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
const containerElementName = 'myReactComponentContainer';
@Component({
selector: 'app-my-component',
template: `<span #${containerElementName}></span>`,
styleUrls: ['./MyReactComponent.scss'],
encapsulation: ViewEncapsulation.None,
})
export class MyComponentWrapperComponent implements OnChanges, OnDestroy, AfterViewInit {
@ViewChild(containerElementName, {static: false}) containerRef: ElementRef;
@Input() public counter = 10;
@Output() public componentClick = new EventEmitter<void>();
constructor() {
this.handleDivClicked = this.handleDivClicked.bind(this);
}
public handleDivClicked() {
if (this.componentClick) {
this.componentClick.emit();
this.render();
}
}
ngOnChanges(changes: SimpleChanges): void {
this.render();
}
ngAfterViewInit() {
this.render();
}
ngOnDestroy() {
ReactDOM.unmountComponentAtNode(this.containerRef.nativeElement);
}
private render() {
const {counter} = this;
ReactDOM.render(<div className={'i-am-classy'}>
<MyReactComponent counter={counter} onClick={this.handleDivClicked}/>
</div>, this.containerRef.nativeElement);
}
}MyReactComponent.tsx
import * as React from 'react';
import { FunctionComponent, useEffect, useRef, useState } from 'react';
import './MyReactComponent.scss';
export interface IMyComponentProps {
counter: number;
onClick?: () => void;
}
export const MyReactComponent: FunctionComponent<IMyComponentProps> = (props: IMyComponentProps) => {
const timerHandle = useRef<number | null>(null);
const [stateCounter, setStateCounter] = useState(42);
useEffect(() => {
timerHandle.current = +setInterval(() => {
setStateCounter(stateCounter + 1);
}, 2500);
return () => {
if (timerHandle.current) {
clearInterval(timerHandle.current);
timerHandle.current = null;
}
};
});
const {counter: propsCounter, onClick} = props;
const handleClick = () => {
if (onClick) {
onClick();
}
};
return <div className={`my-graph-component`}>
<div className={'comp-props'}>Props counter: {propsCounter}
<span onClick={handleClick}
className={'increase-button'}>click to increase</span>
</div>
<div className={'comp-state'}>State counter: {stateCounter}</div>
</div>;
};https://stackoverflow.com/questions/65102540
复制相似问题