javascript - 错误 ReferenceError: React 未定义 | 在 Angular 中使用 React 组件
问题描述
所以基本上我想将一个 React 组件(一个通知组件)渲染到我的 Angular 项目中。我建立Notification.tsx
import * as React from 'react';
import { FunctionComponent, useEffect, useRef, useState } from 'react';
import { IconButton, Badge, Menu, List, ListItem, ListItemIcon, ListItemText, ListItemSecondaryAction, Avatar } from '@material-ui/core';
import { Notifications, Delete, Event, HourglassEmpty, Alarm } from '@material-ui/icons';
import { makeStyles } from '@material-ui/core/styles';
import { grey } from '@material-ui/core/colors';
export interface NotificationProps { }
export const NotificationComponent: FunctionComponent<NotificationProps> = (props: NotificationProps) => {
return <div className={"row"}>
<IconButton disableRipple={true} aria-label="notification" className="py-3 my-auto"
onClick={handleNotificationMenuClick} aria-controls="notification-drop-down-menu"
aria-haspopup="true">
<Badge badgeContent={4} max={99} color="secondary">
<Notifications />
</Badge>
</IconButton>
</div>
};
包装器组件NotificationWrapper.tsx
import { AfterViewInit, Component, ElementRef, OnChanges, OnDestroy, SimpleChanges, ViewChild, ViewEncapsulation } from '@angular/core';
import { NotificationComponent } from './Notification';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
const containerElementName = 'notificationComponentTemplate';
@Component({
selector: 'react-notification-component',
template: `<span #${containerElementName}></span>`,
encapsulation: ViewEncapsulation.None,
})
export class NotificationWrapper implements OnChanges, OnDestroy, AfterViewInit {
@ViewChild(containerElementName, { static: false }) containerRef: ElementRef;
constructor() { }
ngOnChanges(changes: SimpleChanges): void {
this.render();
}
ngAfterViewInit() {
this.render();
}
ngOnDestroy() {
ReactDOM.unmountComponentAtNode(this.containerRef.nativeElement);
}
private render() {
ReactDOM.render(<div className={'notification-wrapper'}>
<NotificationComponent />
</div>, this.containerRef.nativeElement);
}
}
将此包装器添加app.module.ts
到@NgModule
import { NotificationWrapper } from "../react-components/notification/NotificationWrapper";
@NgModule({
declarations: [
NotificationWrapper,
],
})
使用通知包装器选择器如下:
<div class="col-sm-6">
<react-notification-component></react-notification-component>
</div>
在本地服务时一切正常,当我在这个网站上遇到其他类似问题时:我已经添加"jsx": "react"
到tsconfig.json
,
plugins: [
new webpack.ProvidePlugin({
"React": "react",
})
]
和
externals: {
'react': 'React'
},
到webpack.config.js
. 这是整个文件以供参考。
// Work around for https://github.com/angular/angular-cli/issues/7200
const path = require('path');
const webpack = require('webpack');
// change the regex to include the packages you want to exclude
const regex = /firebase\/(app|firestore)/;
module.exports = {
mode: 'production',
entry: {
// This is our Express server for Dynamic universal
server: './server.ts'
},
externals: {
'./dist/server/main': 'require("./server/main")',
'react': 'React'
},
target: 'node',
node: {
__dirname: false,
__filename: false,
},
resolve: { extensions: ['.ts', '.js'] },
target: 'node',
mode: 'none',
// this makes sure we include node_modules and other 3rd party libraries
externals: [/node_modules/, function (context, request, callback) {
// exclude firebase products from being bundled, so they will be loaded using require() at runtime.
if (regex.test(request)) {
return callback(null, 'commonjs ' + request);
}
callback();
}],
optimization: {
minimize: false
},
output: {
// Puts the output at the root of the dist folder
path: path.join(__dirname, 'dist'),
filename: '[name].js'
},
module: {
noParse: /polyfills-.*\.js/,
rules: [
{ test: /\.ts$/, loader: 'ts-loader' },
{
// Mark files inside `@angular/core` as using SystemJS style dynamic imports.
// Removing this will cause deprecation warnings to appear.
test: /(\\|\/)@angular(\\|\/)core(\\|\/).+\.js$/,
parser: { system: true },
},
]
},
plugins: [
new webpack.ProvidePlugin({
"React": "react",
}),
new webpack.ContextReplacementPlugin(
// fixes WARNING Critical dependency: the request of a dependency is an expression
/(.+)?angular(\\|\/)core(.+)?/,
path.join(__dirname, 'src'), // location of your src
{} // a map of your routes
),
new webpack.ContextReplacementPlugin(
// fixes WARNING Critical dependency: the request of a dependency is an expression
/(.+)?express(\\|\/)(.+)?/,
path.join(__dirname, 'src'),
{}
)
]
};
我的问题是,当我构建我的应用程序时,通知组件未呈现,并且我在控制台中收到此错误ERROR ReferenceError: React is not defined
。有什么我错过的吗?提前致谢。
解决方案
将以下内容添加到tsconfig.json
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"jsx": "react",
}
设置aot
和buildOptimizer
为假angular.json
代替
import * as React from 'react';
import * as ReactDOM from 'react-dom'
和
import React from 'react';
import ReactDOM from 'react-dom';
推荐阅读
- javascript - 如何将 SSo 与 Firebase 身份验证一起用于 Web?
- java - 惰性图结构缓存和并发
- css - 折叠时更改引导导航栏下拉菜单中的字体颜色
- python - Python Pandas Count 具有多个条件和 groupby 的列
- javascript - 如何在没有滚动的情况下在移动 Web 应用程序上启动网页
- c++ - 有没有更简洁的方法来用互斥锁定义我的复制 ctor?
- database - ElasticSearch 7 索引与 ElasticSearch 5 相比太大了
- javascript - JS DOM 节点:Javascript
- windows - Visual Studio c++ 构建工具:VsDevCmd.bat / vcvarsall.bat 无法找到一些 [未知] 路径,因此无法运行
- javascript - NodeJS - 将 MTC(Midi Timecode)“quater message”转换为完整的时间码字符串