我应该可以导出我的App组件文件并将其导入我的index.js。
我收到以下错误
React.createElement:type无效 - 期望一个字符串(对于内置组件)或一个类/函数(对于复合组件)但得到:object
const React = require('react');
const ReactDOM = require('react-dom');
const App = require('./components/App');
require('./index.css');
ReactDOM.render(
<App />,
document.getElementById('app')
);
const React = require('react');
export default class App extends React.Component {
render() {
return (
<div>
Hell World! Wasabi Sauce!
</div>
);
}
}
// module.exports = App;
如果我取消注释module.exports = App;
它会起作用,但我正在尝试使用导出语法。让我疯狂的是另一个项目,我在这里完全做同样的事情并且工作正常:(
答案 0 :(得分:9)
您遇到的问题是混合了两个不同的模块系统,它们的方式不同resolved and implemented。 CommonJS modules是动态的,与ES6 modules静态可分析相反。
像Babel这样的工具现在将ES6模块转换为CommonJS,因为native support is not ready yet。但是,存在微妙的差异。
通过使用default export (exports default
),转换器发出了一个具有{ default }
属性的CommonJS模块,因为在ES6模块中可以命名和默认导出。以下示例是完全有效的ES6模块:
export default class Test1 { }
export class Test2 { }
这会在转换后导致{ default, Test2 }
CommonJS模块,并且使用require
将该对象作为返回值。
为了在CommonJS中导入ES6模块的默认导出,您必须使用require(module).default
语法,原因如上所述。
当导入模块出现问题时,React尝试渲染组件时,此错误非常常见。大多数情况下,这是由于模块中缺少export
或路径问题(相对路径是某种笑话)而没有正确的工具,这可能导致严重的毛发拉动。
在这种情况下,React无法渲染通用对象{__esModule: true, default: function}
,只是抛出错误。
使用require
时,可以打印出所需的模块,以查看可能有助于调试问题的内容。
作为旁注,除非您确实需要,否则请不要将CommonJS模块与ES6模块混合使用。 import
/ export
语法保留给ES6模块。使用CommonJS模块时,只需使用module.exports
并使用require
导入它们。在未来,大多数开发人员将使用标准模块格式。在那之前,将它们混合在一起时要小心。
答案 1 :(得分:6)
......它很简单:
const MyModule = require('./MyModule');
VS
const {MyModule} = require('./MyModule');
答案 2 :(得分:1)
以防万一其他人也碰到了...
我曾经遇到过同样的问题,但仅在运行jest
测试代码时才遇到。我遇到了相同的上述错误:
React.createElement:类型无效-预期为字符串(对于内置组件)或类/函数(对于复合组件),但得到:object
如果您的项目碰巧正在使用打字稿,但是您正在使用jest
测试(内部使用多种模块系统-包括CommonJS require
语法),则仍然可以通过以下方式进行此错误测试: jest
(如果您使用
import React from 'react';
子组件中的语法,而不是打字稿变体:
import * as React from 'react';
这是一个奇怪的错误,并且很难捕获,因为应用程序可以通过两种导入方法正常运行,但是对主组件的jest
测试可能会失败,直到将子组件更新为使用第二个组件为止react语法(同样,对于使用jest
测试使用打字稿的语法)。
答案 3 :(得分:0)
ES6模块令人困惑。如果将它们与NodeJS commonJS模块模式混合使用,将会更加混乱;),
如果您使用的是Frontend代码,则建议使用一种样式,最好使用ES6模块。 我编写了一个示例应用程序以更好地理解它。
答案 4 :(得分:0)
我面临着同样的问题, 我做了这个把戏,为我工作,
您只需要将export
放在class App
之前,
export class App extends Component {
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
}
export default App;
您还可以检查您使用的路由器, 我已经为我使用了这个作品,
npm install react-router-dom@next --save