Javascript React.createElement: type is invalid -- 需要一个字符串(对于内置组件)或一个类/函数(对于复合组件)但得到:object

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43969578/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 02:16:16  来源:igfitidea点击:

React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object

javascriptreactjsecmascript-6exportcommonjs

提问by Leon Gaban

Expected

预期的

I should be able to export my App component file and import it into my index.js.

我应该能够导出我的 App 组件文件并将其导入到我的 index.js 中。

Results

结果

I get the following error

我收到以下错误

React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object

React.createElement: type is invalid -- 需要一个字符串(对于内置组件)或一个类/函数(对于复合组件)但得到:object



My index.js

我的 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')
);

Then in my components/App.js

然后在我的 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;

If I uncomment module.exports = App;it will work, but I'm trying to use the export syntax. What is driving me nuts is in another project I am doing the exact same thing here and it's working fine :(

如果我取消注释module.exports = App;它会起作用,但我正在尝试使用导出语法。让我发疯的是在另一个项目中我在这里做完全相同的事情并且它工作正常:(

回答by Przemys?aw Zalewski

The issue you have encountered was caused by mixing two different module systems which differ in the way they are resolved and implemented. CommonJS modulesare dynamic and contrary to that ES6 modulesare statically analyzable.

您遇到的问题是由两种不同的模块系统混合引起的,它们的解决和实现方式各不相同。CommonJS 模块是动态的,与ES6 模块是静态可分析的相反。

Tools like Babeltranspile ES6 modules to CommonJS as for now because native support is not ready yet. But, there are subtle differences. By using default export (exports default)the transpiler emitted a CommonJS module with { default }property as there can be named and default export alongside in ES6 module. Following example is perfectly valid ES6 module:

Babel这样的工具目前将 ES6 模块转换为 CommonJS,因为原生支持还没有准备好。但是,存在细微的差异。通过使用默认导出(exports default,转译器发出了一个带有{ default }属性的 CommonJS 模块,因为在 ES6 模块中可以有命名和默认导出。以下示例是完全有效的 ES6 模块:

export default class Test1 { }
export class Test2 { }

This would result in { default, Test2 }CommonJS module after transpiling and by using requireyou get that object as a return value.

这将{ default, Test2 }在转译后产生CommonJS 模块,并通过使用require该对象作为返回值。

In order to import ES6 module's default export in CommonJS you must use require(module).defaultsyntax by the reasons mentioned above.

为了在 CommonJS 中导入 ES6 模块的默认导出,require(module).default由于上述原因,您必须使用语法。



Debugging React.createElement: type is invalid errors

调试 React.createElement: type is invalid 错误

This error is very common when React tries to render a component when there is an issue with the imported module. Most of the time this is caused by missing exportin the module or issues with the path (relative paths are some kind of a joke) and without proper tooling, this may lead to serious hair pulling.

当 React 尝试在导入的模块出现问题时渲染组件时,此错误非常常见。大多数情况下,这是由export模块中缺失或路径问题(相对路径是某种笑话)引起的,如果没有适当的工具,这可能会导致严重的头发拉扯。

In this case, React couldn't render generic object {__esModule: true, default: function}and just threw an error. When using requirethere is a possibility to just print out required module to see it's contents which may help to debug the issue.

在这种情况下,React 无法渲染通用对象{__esModule: true, default: function},只会抛出一个错误。使用时require,可以只打印出所需的模块以查看其内容,这可能有助于调试问题。



As a side note, please don't mix CommonJS modules with ES6 modules unless you really need. import/exportsyntax is reserved for the ES6 modules. When using CommonJS modules, just use module.exportsand use requireto import them. In the future, most developers will be using standard module format. Until then, be careful when mixing them together.

作为旁注,除非您确实需要,否则请不要将 CommonJS 模块与 ES6 模块混合使用。import/export语法是为 ES6 模块保留的。使用 CommonJS 模块时,只需要 usemodule.exports和 userequire来导入它们。将来,大多数开发人员将使用标准模块格式。在此之前,将它们混合在一起时要小心。

回答by Mick

Very often..

常常..

...it is as simple as:

...它很简单:

const MyModule = require('./MyModule');

vs

对比

const {MyModule} = require('./MyModule');

回答by Anand

ES6 modules are confusing. If we mix them with NodeJS commonJS module pattern, it will be more confusing ;) ,

ES6 模块令人困惑。如果我们将它们与 NodeJS 的 commonJS 模块模式混合在一起,会更加混乱 ;) ,

I'd recommend use one single style, preferrably ES6 modules if you are working in Frontend code. I wrote one sample app to understand it better.

如果您在前端代码中工作,我建议使用单一样式,最好使用 ES6 模块。我写了一个示例应用程序来更好地理解它。

https://github.com/Sutikshan/es-bits/tree/master/modules

https://github.com/Sutikshan/es-bits/tree/master/modules

回答by Ashish Kamble

I was facing same issue, i did this trick, worked for me,

我遇到了同样的问题,我做了这个技巧,对我有用,

you just need to put exportbefore class App,

你只需要在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;

you can also check your router you are using, I have used this works for me,

你也可以检查你正在使用的路由器,我已经用过这对我有用,

npm install react-router-dom@next --save

回答by cjn

Just in case someone else runs into this also...
I was facing this same issue, but only when running my jesttesting code. I got the same aforementioned error:

以防万一其他人也
遇到这个问题......我也面临着同样的问题,但只有在运行我的jest测试代码时。我得到了同样的上述错误:

React.createElement: type is invalid — expected a string (for built-in components) or a class/function (for composite components) but got: object

React.createElement: type is invalid — 期望一个字符串(对于内置组件)或一个类/函数(对于复合组件)但得到:object

If your project happens to be using typescript but you're using jesttesting (which uses a mix of module systems internally - including CommonJS requiresyntax), you can still get this error testing with jestif you use the

如果您的项目碰巧正在使用打字稿,但您正在使用jest测试(它在内部使用混合模块系统 - 包括 CommonJSrequire语法),jest如果您使用

import React from 'react';

syntax in a sub-component instead of the typescript variant:

子组件中的语法而不是 typescript 变体:

import * as React from 'react';

It's a weird error & can be hard to catch, since the app may run fine with either import approach, but the jesttesting of a primary component may fail until the sub-component is updated to use the second react syntax (again, for those using typescript with jesttesting).

这是一个奇怪的错误并且很难捕捉到,因为应用程序可能使用任何一种导入方法都可以正常运行,但是jest在子组件更新为使用第二个 react 语法之前,主组件的测试可能会失败(同样,对于那些使用带jest测试的打字稿)。