未捕获的不变违规:元素类型无效(反应、webpack、循环导入)
Uncaught Invariant Violation: Element type is invalid (react, webpack, circular imports)
首先,我想说我是 javascript 的新手,如果我的问题很简单但我无法弄清楚这种情况,请提前致歉。如果需要,我会更新 post。
我想将我当前的应用程序迁移到单页应用程序。我有 3 个主要页面 PageA、PageB 和 PageC(在反应中我有 3 个主要组件)。我希望能够在这 3 个 pages/components 之间切换。假设我有这个 LogoText,它是代表网站徽标的组件。我想在所有其他组件(包括 PageA)中使用它,当我单击它时,我想呈现主页( PageA )。
所以我试图用 react 和 webpack 构建它。在下面给出的这个简单示例中,我有一个主页组件 MainPage.js,它是应该位于主页中的所有组件的父组件,还有一个 LogoText 组件,当有人单击它时,它应该呈现 MainPage 组件。当所有这些组件都在一个文件中并且我不使用 require() 时,一切都运行良好,但是当我使用 require()[ 将我的应用程序分解为模块时=50=] 并用 webpack 打包我得到了奇怪的行为。我可以加载 MainPage 组件并且 LogoText 组件在 MainPage 中正确显示,但是当我单击 LogoText 时,我得到“未捕获的不变违规:元素类型无效”异常(click for screenshot)
第一个例外:
react.js:18798 警告:React.createElement:类型不应为空、未定义、布尔值或数字。它应该是一个字符串(对于 DOM 元素)或一个 ReactClass(对于复合组件)。
第二个例外:
react.js:18354 Uncaught Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) 但得到:object.
我有以下 3 类:
main.js:
var MainPage = require("./MainPage.js")
ReactDOM.render(
<MainPage />,
document.getElementById('content')
);
MainPage.js:
var LogoText = require("./LogoText.js")
var MainPage = React.createClass({
render: function() {
return (
<div>
Hello page,
<LogoText />
</div>
);
}
});
module.exports = MainPage;
LogoText.js
var MainPage = require("./MainPage.js")
var LogoText = React.createClass({
changePage: function(e) {
ReactDOM.render(
<MainPage />,
document.getElementById('content')
);
},
render: function() {
return (
<span onClick={this.changePage}>logo</span>
);
}
});
module.exports = LogoText;
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>React Tutorial</title>
<!-- Not present in the tutorial. Just for basic styling. -->
<link rel="stylesheet" href="css/base.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.6.16/browser.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.5/marked.min.js"></script>
</head>
<body>
<div id="content"></div>
<script src="scripts/bundle.js"></script>
</body>
</html>
更新 1:
这是我的 webpack.config.js:
module.exports = {
entry: "./src/scripts/main.js",
output: {
path: "./src/scripts",
filename: "bundle.js"
},
module: {
loaders: [
{ test: /\.css$/, loader: "style!css" },
{ test: /\.js$/, loader: 'jsx-loader?insertPragma=React.DOM&harmony'},
]
},
externals: {
//don't bundle the 'react' npm package with our bundle.js
//but get it from a global 'React' variable
'react': 'React'
},
resolve: {
extensions: ['', '.js', '.jsx']
}
};
好吧,显然我的直觉是正确的"I can guess that it is because of the circular require()"。答案在这里:“”。
我认为 react router 将是实现这一点的正确方法。我会试试的,稍后我会post这里的结果:)
更新 1:
React 路由器正是我正在寻找的。 This is the exact tutorial that solved my problem.
首先,我想说我是 javascript 的新手,如果我的问题很简单但我无法弄清楚这种情况,请提前致歉。如果需要,我会更新 post。
我想将我当前的应用程序迁移到单页应用程序。我有 3 个主要页面 PageA、PageB 和 PageC(在反应中我有 3 个主要组件)。我希望能够在这 3 个 pages/components 之间切换。假设我有这个 LogoText,它是代表网站徽标的组件。我想在所有其他组件(包括 PageA)中使用它,当我单击它时,我想呈现主页( PageA )。
所以我试图用 react 和 webpack 构建它。在下面给出的这个简单示例中,我有一个主页组件 MainPage.js,它是应该位于主页中的所有组件的父组件,还有一个 LogoText 组件,当有人单击它时,它应该呈现 MainPage 组件。当所有这些组件都在一个文件中并且我不使用 require() 时,一切都运行良好,但是当我使用 require()[ 将我的应用程序分解为模块时=50=] 并用 webpack 打包我得到了奇怪的行为。我可以加载 MainPage 组件并且 LogoText 组件在 MainPage 中正确显示,但是当我单击 LogoText 时,我得到“未捕获的不变违规:元素类型无效”异常(click for screenshot)
第一个例外:
react.js:18798 警告:React.createElement:类型不应为空、未定义、布尔值或数字。它应该是一个字符串(对于 DOM 元素)或一个 ReactClass(对于复合组件)。
第二个例外:
react.js:18354 Uncaught Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) 但得到:object.
我有以下 3 类:
main.js:
var MainPage = require("./MainPage.js")
ReactDOM.render(
<MainPage />,
document.getElementById('content')
);
MainPage.js:
var LogoText = require("./LogoText.js")
var MainPage = React.createClass({
render: function() {
return (
<div>
Hello page,
<LogoText />
</div>
);
}
});
module.exports = MainPage;
LogoText.js
var MainPage = require("./MainPage.js")
var LogoText = React.createClass({
changePage: function(e) {
ReactDOM.render(
<MainPage />,
document.getElementById('content')
);
},
render: function() {
return (
<span onClick={this.changePage}>logo</span>
);
}
});
module.exports = LogoText;
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>React Tutorial</title>
<!-- Not present in the tutorial. Just for basic styling. -->
<link rel="stylesheet" href="css/base.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.6.16/browser.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.5/marked.min.js"></script>
</head>
<body>
<div id="content"></div>
<script src="scripts/bundle.js"></script>
</body>
</html>
更新 1: 这是我的 webpack.config.js:
module.exports = {
entry: "./src/scripts/main.js",
output: {
path: "./src/scripts",
filename: "bundle.js"
},
module: {
loaders: [
{ test: /\.css$/, loader: "style!css" },
{ test: /\.js$/, loader: 'jsx-loader?insertPragma=React.DOM&harmony'},
]
},
externals: {
//don't bundle the 'react' npm package with our bundle.js
//but get it from a global 'React' variable
'react': 'React'
},
resolve: {
extensions: ['', '.js', '.jsx']
}
};
好吧,显然我的直觉是正确的"I can guess that it is because of the circular require()"。答案在这里:“
我认为 react router 将是实现这一点的正确方法。我会试试的,稍后我会post这里的结果:)
更新 1:
React 路由器正是我正在寻找的。 This is the exact tutorial that solved my problem.