¿Cómo importar y exportar componentes con React + ES6 + webpack?

135

Estoy jugando con Reacty ES6usando babely webpack. Quiero construir varios componentes en diferentes archivos, importarlos en un solo archivo y agruparlos conwebpack

Digamos que tengo algunos componentes como este:

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

Usando webpack y siguiendo su tutorial, tengo main.js:

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

Después de compilar el proyecto y ejecutarlo, aparece el siguiente error en la consola de mi navegador:

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`.

¿Qué estoy haciendo mal? ¿Cómo puedo importar y exportar correctamente mis componentes?

atrapado
fuente
exportdetalles de palabras clave aquí . Actualmente no es compatible de forma nativa con ninguno de los navegadores web.
RBT

Respuestas:

128

Intente predeterminar las exportaciones en sus componentes:

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>
      );
    }
}

Al usar el valor predeterminado, expresa que será miembro de ese módulo que se importaría si no se proporciona un nombre de miembro específico. También puede expresar que desea importar el miembro específico llamado MyNavbar al hacerlo: import {MyNavbar} desde './comp/my-navbar.jsx'; en este caso, no se necesita por defecto

Emilio Rodriguez
fuente
Esto no funciona para mi. Cuando lo ejecuto en mi propio proyecto recibo un error que dice que no puede importar el componente. Alguna idea de por qué?
BHouwens
66
Al usar el valor predeterminado, expresa que será miembro de ese módulo que se importaría si no se proporciona un nombre de miembro específico. También puede expresar que desea importar el miembro específico llamado MyNavbar al hacerlo: import {MyNavbar} desde './comp/my-navbar.jsx'; en este caso, no se necesita ningún defecto
Emilio Rodriguez
103

Ajuste de componentes con llaves si no hay exportaciones predeterminadas:

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

o importar múltiples componentes desde un archivo de módulo único

import {MyNavbar1, MyNavbar2} from './module';
nof
fuente
44
Esta debería ser la respuesta aceptada. Estos están named exportsen es6 y son una forma más segura de exportar developer.mozilla.org/en/docs/web/javascript/reference/… que usardefault
kaushik94 el
"Ajustar componentes con llaves si no hay exportaciones predeterminadas" es suficiente. Tnx
Eugen Sunic
1
tal vez esto pueda ayudar: en mi caso, faltaba el './' dentro de la ruta. Eso suena un poco extraño debido a que el componente está en el mismo nivel de carpeta.
Alessandro DS
99

Para exportar un solo componente en ES6, puede usar export defaultlo siguiente:

class MyClass extends Component {
 ...
}

export default MyClass;

Y ahora usa la siguiente sintaxis para importar ese módulo:

import MyClass from './MyClass.react'

Si está buscando exportar múltiples componentes desde un solo archivo, la declaración se vería así:

export class MyClass1 extends Component {
 ...
}

export class MyClass2 extends Component {
 ...
}

Y ahora puede usar la siguiente sintaxis para importar esos archivos:

import {MyClass1, MyClass2} from './MyClass.react'
josephmisiti
fuente
10

MDN tiene muy buena documentación para todas las nuevas formas de importar y exportar módulos es ES 6 Import-MDN . Una breve descripción de lo que respecta a su pregunta que podría haber:

  1. Declarado el componente que exportaban como el componente 'por defecto' que este módulo exportaba: export default class MyNavbar extends React.Component {, y así, cuando Importar su 'MyNavbar' usted no tiene que poner llaves alrededor de él: import MyNavbar from './comp/my-navbar.jsx';. Sin embargo, no poner llaves alrededor de una importación es decirle al documento que este componente se declaró como un 'valor predeterminado de exportación'. Si no fuera así, recibirá un error (como lo hizo).

  2. Si no desea declarar su 'MyNavbar' como una exportación predeterminada al exportarla export class MyNavbar extends React.Component {, entonces tendría que ajustar su importación de 'MyNavbar entre llaves: import {MyNavbar} from './comp/my-navbar.jsx';

Creo que dado que solo tenía un componente en su archivo './comp/my-navbar.jsx' es genial hacer que sea la exportación predeterminada. Si hubiera tenido más componentes como MyNavbar1, MyNavbar2, MyNavbar3, entonces no haría que ninguno de ellos fuera un valor predeterminado y que importara los componentes seleccionados de un módulo cuando el módulo no haya declarado que algo es predeterminado: import {foo, bar} from "my-module";donde foo y bar son múltiples miembros de su módulo.

Definitivamente lea el documento MDN, tiene buenos ejemplos para la sintaxis. Espero que esto ayude con un poco más de explicación para cualquiera que esté buscando jugar con ES 6 e importar / exportar componentes en React.

Carol Gonzalez
fuente
4

Espero que esto sea útil

Paso 1: App.js (módulo principal) importa el módulo de inicio de sesión

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

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

export default App;

Paso 2: cree la carpeta de inicio de sesión y cree el archivo login.js y personalice sus necesidades, se procesará automáticamente en App.js Ejemplo de 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;
Vidhyapathi Kandhasamy
fuente
2

Hay dos formas diferentes de importar componentes en reaccionar y la forma recomendada es la forma de componentes

  1. Forma de biblioteca (no recomendado)
  2. Forma componente (recomendado)

Explicación detallada de PFB

Forma de importación de la biblioteca

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

Esto es agradable y práctico, pero no solo agrupa Button y FlatButton (y sus dependencias) sino todas las bibliotecas.

Forma componente de importar

Una forma de aliviarlo es tratar de importar o requerir solo lo que se necesita, digamos el componente. Usando el mismo ejemplo:

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

Esto solo agrupará Button, FlatButton y sus respectivas dependencias. Pero no toda la biblioteca. Por lo tanto, trataría de deshacerme de todas las importaciones de su biblioteca y utilizar el componente en su lugar.

Si no está utilizando muchos componentes, debería reducir considerablemente el tamaño de su archivo incluido.

Hemadri Dasari
fuente