React.createElement: type is invalid - 期望一个字符串(对于内置组件)或一个类/函数(对于复合组件)但是得到:对象
Posted
技术标签:
【中文标题】React.createElement: type is invalid - 期望一个字符串(对于内置组件)或一个类/函数(对于复合组件)但是得到:对象【英文标题】:React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object 【发布时间】:2017-10-13 15:40:56 【问题描述】:预期
我应该能够导出我的 App 组件文件并将其导入到我的 index.js 中。
结果
我收到以下错误
React.createElement: type is invalid -- 期望一个字符串(对于内置组件)或一个类/函数(对于复合组件)但得到:对象
我的 index.js
const React = require('react');
const ReactDOM = require('react-dom');
const App = require('./components/App');
require('./index.css');
ReactDOM.render(
<App />,
document.getElementById('app')
);
然后在我的 components/App.js 中
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;
它将起作用,但我正在尝试使用导出语法。让我发疯的是在另一个项目中,我在这里做同样的事情,而且工作正常:(
【问题讨论】:
请不要将 CommonJS 模块与 ES6 模块混用。import
/export
语法是为 ES6 模块保留的。使用 CommonJS 模块时,只需使用 module.exports
。
我不想混合它们,但由于某种原因,React 不喜欢我的 ES6 导出。在这个项目中,我在其他项目中使用它很好。
这可能取决于您的转译器/捆绑器处理 ES6 模块的方式。当路径错误时,'React.createElement: type is invalid' 错误很常见。你能不能 console.log(require('./components/App'))
看看导出了什么?
我知道Object __esModule: true, default: function
和default.name
是App
。我的路径是正确的,因为 commonJS 方式 module.exports 有效。
那么你应该使用const App = require('./components/App').default
来获取组件(默认导出)。
【参考方案1】:
您遇到的问题是由两种不同的模块系统混合引起的,它们的方式不同,它们是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.createElement: type is invalid 错误
当 React 在导入的模块出现问题时尝试渲染组件时,此错误非常常见。大多数情况下,这是由于模块中缺少export
或路径问题(相对路径是某种玩笑)而没有适当的工具,这可能会导致严重的头发拉扯。
在这种情况下,React 无法渲染通用对象 __esModule: true, default: function
并且只是抛出了一个错误。
使用require
时,可以打印出所需的模块以查看其内容,这可能有助于调试问题。
附带说明,除非您确实需要,否则请不要将 CommonJS 模块与 ES6 模块混合使用。 import
/export
语法是为 ES6 模块保留的。使用 CommonJS 模块时,只需使用 module.exports
并使用 require
导入它们。将来,大多数开发人员将使用标准模块格式。在此之前,将它们混合在一起时要小心。
【讨论】:
【参考方案2】:经常..
...就这么简单:
const MyModule = require('./MyModule');
对
const MyModule = require('./MyModule');
【讨论】:
非常感谢兄弟,我使用“react-data-components”模块对数据进行排序、过滤和页面导航。以前我像 ==>import DataTable from 'react-data-components' 一样导入;然后我得到了这个错误。但是在添加花括号后它工作正常。 ==> 从 'react-data-components' 导入 DataTable;我几乎浪费了3个小时的时间。再次感谢兄弟 请参考此链接::reviewdb.io/questions/1527838077232/… 用大括号括起来有什么作用?我和 OP 有同样的问题,但 有帮助【参考方案3】:我遇到了同样的问题, 我做了这个把戏,为我工作,
您只需将export
放在class App
之前,
export class App extends Component
render()
return (
<div className="App">
<header className="App-header">
<img src=logo className="App-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
【讨论】:
【参考方案4】:以防万一其他人也遇到这种情况...
我遇到了同样的问题,但仅在运行我的 jest
测试代码时。我得到了同样的上述错误:
React.createElement: type is invalid — 期望一个字符串(对于内置组件)或一个类/函数(对于复合组件)但得到:对象
如果您的项目恰好使用 typescript,但您正在使用 jest
测试(它在内部使用混合模块系统 - 包括 CommonJS require
语法),您仍然可以使用 jest
if 进行此错误测试你用
import React from 'react';
子组件中的语法而不是打字稿变体:
import * as React from 'react';
这是一个奇怪的错误并且很难捕捉到,因为应用程序可以使用任何一种导入方法都可以正常运行,但是主要组件的 jest
测试可能会失败,直到子组件更新为使用第二种反应语法(同样,对于那些使用带有jest
测试的打字稿的人)。
【讨论】:
【参考方案5】:ES6 模块令人困惑。如果我们将它们与 NodeJS 的 commonJS 模块模式混合使用,会更加混乱 ;) ,
如果您使用前端代码,我建议使用单一样式,最好使用 ES6 模块。 为了更好地理解它,我编写了一个示例应用程序。
https://github.com/Sutikshan/es-bits/tree/master/modules
【讨论】:
【参考方案6】:对我来说,这是循环依赖的问题。
//simplistic example
//a.js
import foo from './b.js'
export const bar = foo
//b.js
import bar from './a.js'
export const foo = bar
【讨论】:
以上是关于React.createElement: type is invalid - 期望一个字符串(对于内置组件)或一个类/函数(对于复合组件)但是得到:对象的主要内容,如果未能解决你的问题,请参考以下文章
react-router 报错React.createElement: type is invalid ...解决方法
React.createElement: type is invalid - 期望一个字符串(对于内置组件)或一个类/函数(对于复合组件)但是得到:对象
为啥 React.createElement() 会创建一个对象?
React底层 render, createElement 方法作用梳理