如何使用 React + ES6 + webpack 导入和导出组件?

Posted

技术标签:

【中文标题】如何使用 React + ES6 + webpack 导入和导出组件?【英文标题】:How to import and export components using React + ES6 + webpack? 【发布时间】:2016-03-01 14:03:53 【问题描述】:

我正在使用babelwebpackReactES6。我想在不同的文件中构建几个组件,导入一个文件并将它们与webpack捆绑在一起

假设我有几个这样的组件:

我的导航栏.jsx

import React from 'react';
import Navbar from 'react-bootstrap/lib/Navbar';

export class MyNavbar extends React.Component 
    render()
      return (
        <Navbar className="navbar-dark" fluid>
        ...
        </Navbar>
      );
    

main-page.jsx

import React from 'react';
import ReactDOM from 'react-dom';

import MyNavbar from './comp/my-navbar.jsx';

export class MyPage extends React.Component
  render()
    return(
        <MyNavbar />
        ...
    );
  


ReactDOM.render(
  <MyPage />,
  document.getElementById('container')
);

使用 webpack 并按照他们的教程,我有 main.js:

import MyPage from './main-page.jsx';

构建项目并运行后,我在浏览器控制台中收到以下错误:

Error: Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. Check the render method of `MyPage`.

我做错了什么?如何正确导入和导出我的组件?

【问题讨论】:

export 关键字详细信息here。目前,任何网络浏览器都不支持它。 【参考方案1】:

尝试默认在您的组件中设置导出:

import React from 'react';
import Navbar from 'react-bootstrap/lib/Navbar';

export default class MyNavbar extends React.Component 
    render()
      return (
        <Navbar className="navbar-dark" fluid>
        ...
        </Navbar>
      );
    

通过使用默认值,您表示将成为该模块中的成员,如果没有提供特定的成员名称,则该模块将被导入。您还可以通过以下方式表达您想要导入名为 MyNavbar 的特定成员: import MyNavbar from './comp/my-navbar.jsx';在这种情况下,不需要默认值

【讨论】:

这对我不起作用。在我自己的项目中运行它时,我收到错误消息说它无法导入组件。任何想法为什么? 使用默认值表示您将成为该模块中的成员,如果没有提供特定的成员名称,该模块将被导入。您还可以通过以下方式表达您想要导入名为 MyNavbar 的特定成员: import MyNavbar from './comp/my-navbar.jsx';在这种情况下,不需要默认值【参考方案2】:

如果没有默认导出,则用大括号包裹组件:

import MyNavbar from './comp/my-navbar.jsx';

或从单个模块文件中导入多个组件

import MyNavbar1, MyNavbar2 from './module';

【讨论】:

这应该是公认的答案。这些是 es6 中的 named exports 和导出 developer.mozilla.org/en/docs/web/javascript/reference/… 比使用 default 更安全的方法 “如果没有默认导出,用大括号包裹组件”就足够了。 Tnx 也许这会有所帮助:在我的情况下,它缺少路径中的“./”。这听起来有点奇怪,因为组件位于同一文件夹级别。【参考方案3】:

要在 ES6 中导出单个组件,可以使用export default,如下所示:

class MyClass extends Component 
 ...


export default MyClass;

现在您使用以下语法导入该模块:

import MyClass from './MyClass.react'

如果您希望从单个文件中导出多个组件,则声明应如下所示:

export class MyClass1 extends Component 
 ...


export class MyClass2 extends Component 
 ...

现在您可以使用以下语法来导入这些文件:

import MyClass1, MyClass2 from './MyClass.react'

【讨论】:

【参考方案4】:

MDN 为所有导入和导出模块的新方法提供了非常好的文档,即 ES 6 Import-MDN。关于您的问题的简要说明:

    将您正在导出的组件声明为该模块正在导出的“默认”组件: export default class MyNavbar extends React.Component ,因此在导入“MyNavbar”时,您不必在其周围加上花括号:import MyNavbar from './comp/my-navbar.jsx';。 但是,不在导入周围放置花括号会告诉文档该组件已被声明为“导出默认值”。如果不是,您将收到错误消息(就像您所做的那样)。

    如果您不想在导出时将 'MyNavbar' 声明为默认导出:export class MyNavbar extends React.Component ,那么您必须将导入的 'MyNavbar 包装在花括号中: import MyNavbar from './comp/my-navbar.jsx';

我认为,由于您的“./comp/my-navbar.jsx”文件中只有一个组件,因此将其设为默认导出非常酷。如果您有更多组件,例如 MyNavbar1、MyNavbar2、MyNavbar3,那么我不会将它们设为默认值,并在模块未声明任何您可以使用的默认值时导入模块的选定组件:@987654326 @ 其中 foo 和 bar 是模块的多个成员。

一定要阅读 MDN 文档,它有很好的语法示例。希望这有助于为任何想要在 React 中玩 ES 6 和组件导入/导出的人提供更多的解释。

【讨论】:

【参考方案5】:

我希望这是有帮助的

第一步:App.js 是(主模块)导入登录模块

import React,  Component  from 'react';
import './App.css';
import Login from './login/login';

class App extends Component 
  render() 
    return (
      <Login />
    );
  


export default App;

第 2 步:创建登录文件夹并创建 login.js 文件并自定义您的需求,它会自动呈现到 App.js 示例 Login.js

import React,  Component  from 'react';
import '../login/login.css';

class Login extends Component 
  render() 
    return (
      <div className="App">
        <header className="App-header">
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <p className="App-intro">
          To get started, edit <code>src/App.js</code> and save to reload.
        </p>
      </div>
    );
  


export default Login;

【讨论】:

【参考方案6】:

react 中引入组件有两种不同的方式,推荐的方式是组件方式

    库方式(不推荐) 组件方式(推荐)

PFB详解

库的导入方式

import  Button  from 'react-bootstrap';
import  FlatButton  from 'material-ui';

这很好用,但它不仅捆绑了 Button 和 FlatButton(及其依赖项),还捆绑了整个库。

组件的导入方式

缓解它的一种方法是尝试只导入或需要需要的东西,比如说组件方式。使用相同的示例:

import Button from 'react-bootstrap/lib/Button';
import FlatButton from 'material-ui/lib/flat-button';

这只会捆绑 Button、FlatButton 及其各自的依赖项。但不是整个图书馆。所以我会尝试摆脱你所有的库导入并改用组件方式。

如果您不使用大量组件,那么它应该会大大减少捆绑文件的大小。

【讨论】:

以上是关于如何使用 React + ES6 + webpack 导入和导出组件?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 ReactDOM 直接渲染 React 组件(ES6 API)?

如何命名 es6 类(用于 React 组件)

如何在 react.js ES6 中使用道具设置状态

如何在 React 中使用 ES6 类设置初始状态?

react开发中如何使用require.ensure加载es6风格的模块

如何将 ES6 与 React Native 结合使用