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


135

我在玩ReactES6使用babelwebpack。我想在不同的文件中构建多个组件,将其导入单个文件并将其与webpack

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

my-navbar.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关键字详细信息在这里。当前,任何网络浏览器都不支持它本身。
RBT

Answers:


128

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

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的特定成员:从'./comp/my-navbar.jsx'导入{MyNavbar};在这种情况下,不需要默认值


这对我不起作用。在我自己的项目中运行它时,出现错误,提示它无法导入组件。有什么想法吗?
BHouwens '16

6
通过使用默认值,您表示将成为该模块的成员,如果未提供特定的成员名称,则将导入该模块。您也可以这样做表示自己要导入名为MyNavbar的特定成员:从'./comp/my-navbar.jsx'导入{MyNavbar};在这种情况下,不需要默认设置
Emilio Rodriguez

103

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

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

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

import {MyNavbar1, MyNavbar2} from './module';

4
这应该是公认的答案。这些都named exports在es6中,并且是比使用default
kaushik94 '16

“如果没有默认导出,则用大括号包裹组件”就足够了。Tnx
尤金·桑尼奇'17

1
也许这可以有所帮助:就我而言,它在路径中丢失了“ ./”。听起来有点奇怪,因为组件位于同一文件夹级别。
亚历山德罗DS

99

要在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'

10

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

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

  2. 如果在导出时不希望将“ MyNavbar”声明为默认导出:export class MyNavbar extends React.Component {,则必须将“ MyNavbar”的导入用大括号括起来: import {MyNavbar} from './comp/my-navbar.jsx';

我认为,由于您的'./comp/my-navbar.jsx'文件中只有一个组件,因此使其成为默认导出很酷。如果您有更多组件,例如MyNavbar1,MyNavbar2,MyNavbar3,那么我不会将其中任何一个设置为默认值,并且在模块未声明任何默认值的情况下导入模块的选定组件,您可以使用:import {foo, bar} from "my-module";where foo和bar是模块的多个成员。

一定要阅读MDN文档,其中包含有关语法的良好示例。希望这对希望在React中使用ES 6和组件导入/导出的任何人提供更多的解释。


4

希望这对您有所帮助

步骤1: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;

2

在React中导入组件有两种不同的方式,推荐的方式是组件方式

  1. 图书馆方式(不推荐)
  2. 组件方式(推荐)

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及其各自的依赖项。但不是整个图书馆。因此,我将尝试摆脱所有库导入,而改用组件方式。

如果您不使用很多组件,那么它将大大减少捆绑文件的大小。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.