![](/img/trans.png)
[英]React.createElement: type is invalid - expected a string (for built-in components) or a class/function (for composite components) but got: undefined
[英]React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object
我應該能夠導出我的 App 組件文件並將其導入到我的 index.js 中。
我收到以下錯誤
React.createElement: 類型無效——需要一個字符串(對於內置組件)或一個類/函數(對於復合組件)但得到:對象
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;
它會起作用,但我正在嘗試使用導出語法。 讓我發瘋的是在另一個項目中我在這里做完全相同的事情並且它工作正常:(
您遇到的問題是由兩種不同的模塊系統混合引起的,它們的解決和實現方式各不相同。 CommonJS 模塊是動態的,與ES6 模塊是靜態可分析的相反。
像Babel這樣的工具目前將 ES6 模塊轉換為 CommonJS,因為原生支持還沒有准備好。 但是,存在細微的差異。 通過使用默認導出( 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
導入它們。 將來,大多數開發人員將使用標准模塊格式。 在此之前,將它們混合在一起時要小心。
...它很簡單:
const MyModule = require('./MyModule');
對比
const {MyModule} = require('./MyModule');
我遇到了同樣的問題,我做了這個技巧,對我有用,
你只需要在class App
之前放置export
,
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
以防萬一其他人也遇到這種情況......
我遇到了同樣的問題,但僅在運行我的jest
測試代碼時才遇到。 我得到了同樣的上述錯誤:
React.createElement: type is invalid — 期望字符串(對於內置組件)或類/函數(對於復合組件)但得到:對象
如果您的項目碰巧使用打字稿,但您使用的是jest
測試(它在內部使用混合模塊系統 - 包括 CommonJS require
語法),如果您使用jest
,您仍然可以使用jest
此錯誤測試
import React from 'react';
子組件中的語法而不是 typescript 變體:
import * as React from 'react';
這是一個奇怪的錯誤並且很難捕捉到,因為應用程序可能使用任何一種導入方法都可以正常運行,但是主組件的jest
測試可能會失敗,直到子組件更新為使用第二個 react 語法(同樣,對於那些使用打字稿進行jest
測試)。
ES6 模塊令人困惑。 如果我們將它們與 NodeJS 的 commonJS 模塊模式混合在一起,會更加混亂 ;) ,
如果您在前端代碼中工作,我建議使用單一樣式,最好使用 ES6 模塊。 我寫了一個示例應用程序來更好地理解它。
對我來說,這是循環依賴的問題。
//simplistic example
//a.js
import { foo } from './b.js'
export const bar = foo
//b.js
import { bar } from './a.js'
export const foo = bar
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.