¿Por qué no es válida la opción 'Exportar configuración predeterminada'?

351

Veo que lo siguiente está bien:

const Tab = connect( mapState, mapDispatch )( Tabs );
export default Tab;

Sin embargo, esto es incorrecto:

export default const Tab = connect( mapState, mapDispatch )( Tabs );

Sin embargo, esto está bien:

export default Tab = connect( mapState, mapDispatch )( Tabs );

¿Puede esto explicarse por qué constno es válido export default? ¿Es una adición innecesaria y algo declarado como export defaultse presume una consto tal?

Kayote
fuente
1
export default Tab = connect( mapState, mapDispatch )( Tabs );debería ser export default connect( mapState, mapDispatch )( Tabs );. Está exportando el resultado de la llamada a la función, no la variable Tab.
ThaJay
2
Se requiere una constante o let (y relevante) en el módulo de exportación pero es irrelevante en el módulo de importación, donde el identificador importado siempre es de solo lectura (no se puede asignar). Esto todavía no explica por qué la sintaxis de "exportación predeterminada" difiere de la "exportación" no predeterminada.
Denis Howe

Respuestas:

303

constes como let, es una Declaración Lexical ( Declaración de Variable, Declaración ) utilizada para definir un identificador en su bloque.

Está intentando mezclar esto con la defaultpalabra clave, que espera que una declaración HoistableDeclaration, ClassDeclaration o AssignmentExpression lo siga.

Por lo tanto, es un SyntaxError .


Si desea constalgo, debe proporcionar el identificador y no usarlo default.

exportpor sí mismo acepta una Declaración Variable o Declaración a su derecha.


AFAIK la exportación en sí misma no debería agregar nada a su alcance actual.


Lo siguiente está bienexport default Tab;

Tabse convierte en AssignmentExpression ya que recibe el nombre predeterminado ?

export default Tab = connect( mapState, mapDispatch )( Tabs ); está bien

Aquí Tab = connect( mapState, mapDispatch )( Tabs );hay una AssignmentExpression .

Paul S.
fuente
27
La respuesta es cómo se convierte en un error. La pregunta sigue siendo ¿por qué? La única razón por la que evita el abuso de const de esta manera: exportación por defecto const a = 1, b = 3, c = 4;
Sergey Orlov
77
"AFAIK the export in itself should not add anything to your current scope"Esto no es tan preciso, porque se export const a = 1agrega aa su contexto actual. E incluso export defaulten el caso de las clases, porque también se export default class MyClass {}agrega MyClassa su contexto actual.
Ernesto
44
@SergeyOrlov está de acuerdo en que esto explica cómo esto genera un error, pero arroja poca luz sobre por qué es necesario. Aunque no estoy seguro de que esa sea la única razón, probablemente debería publicar eso como una respuesta por separado, no como un comentario a esta.
Herick
Si hago lo siguiente: let a; export default a;y luego actualizo la variable a cuando ya se ha importado a otro módulo, ¿por qué no se actualiza la variable predeterminada de exportación?
K - La toxicidad en SO está creciendo.
Tengo entendido que, para abreviar, puedes escribir const foo = function bar() {}y también const Foo = class Bar {}, pero no const foo = const bar = 1. Lo mismo para export default, es como const foo =.
zetavg
47

También puede hacer algo como esto si desea exportar por defecto un const / let, en lugar de

const MyComponent = ({ attr1, attr2 }) => (<p>Now Export On other Line</p>);
export default MyComponent

Puedes hacer algo como esto, que no me gusta personalmente.

let MyComponent;
export default MyComponent = ({ }) => (<p>Now Export On SameLine</p>);
Adeel Imran
fuente
19

Si el nombre del componente se explica en el nombre del archivo MyComponent.js, simplemente no nombre el componente, mantiene el código delgado.

import React from 'react'

export default (props) =>
    <div id='static-page-template'>
        {props.children}
    </div>

Actualización : como esto lo etiqueta como desconocido en el seguimiento de la pila, no se recomienda

Kevin Danikowski
fuente
14
¿No tienes problemas con stacktraces? Para mí que está causando que muestra Unknowntodas partes donde es de exportación predeterminado sin nombre
Jurosh
2
Si bien esto funciona, sin duda es algo que todo desarrollador que reacciona fuera del desarrollo de aplicaciones de juguetes debe esforzarse por evitar a toda costa.
li x
1
@lix No pude entender por qué uno debería evitar usar esta sintaxis. ¿Podría explicar o compartir un enlace? Gracias.
sudip
3
@sudip Crear un componente sin nombre no es bueno para el modelo y la representación del componente de reacción.
li x
1
Sin embargo, parece limpio, también Dan Abramov sugiere que deberíamos usar los nombres de función / const adecuados en la declaración del componente: twitter.com/dan_abramov/status/1255229440860262400 ;) "- se mostrará como Anónimo en las trazas de la pila - se mostrará como Desconocido en DevTools - no será revisado por las reglas de pelusa específicas de React - no funcionará con algunas características como Fast Refresh "
Zoltan
9

La respuesta de Paul es la que estás buscando. Sin embargo, como cuestión práctica, creo que puede estar interesado en el patrón que he estado usando en mis propias aplicaciones React + Redux.

Aquí hay un ejemplo simplificado de una de mis rutas, que muestra cómo puede definir su componente y exportarlo como predeterminado con una sola declaración:

import React from 'react';
import { connect } from 'react-redux';

@connect((state, props) => ({
    appVersion: state.appVersion
    // other scene props, calculated from app state & route props
}))
export default class SceneName extends React.Component { /* ... */ }

(Nota: uso el término "Escena" para el componente de nivel superior de cualquier ruta).

Espero que esto sea útil. Creo que es mucho más limpio que el convencional.connect( mapState, mapDispatch )( BareComponent )

Tom
fuente
Lástima que los decoradores no puedan ser utilizados en un componente de función
Eric Kim
@EricKim Bummer. Pero, vale la pena tener en cuenta que la especificación del decorador aún no es definitiva. Tal vez los componentes funcionales no se puedan decorar con el decorador "heredado", pero no sé si se debe a una limitación del diseño heredado, o porque la implementación de los decoradores heredados es incompleta o tiene errores. FWIW: @connectes el único decorador que uso, solo lo uso con componentes que están conectados a una tienda redux, casi cada uno de ellos es una "ruta", y casi todas las rutas deben tener estado (y por lo tanto no puede ser una función pura) .
Tom
8

La respuesta compartida por Paul es la mejor. Para ampliar más,

Solo puede haber una exportación predeterminada por archivo. Mientras que puede haber más de una exportación constante. La variable predeterminada se puede importar con cualquier nombre, mientras que la variable const se puede importar con su nombre particular.

var message2 = 'Estoy exportado';

exportar mensaje predeterminado2;

export const message = 'También estoy exportado'

En el lado de las importaciones, necesitamos importarlo así:

importar {mensaje} desde './test';

o

importar mensaje de './test';

Con la primera importación, la variable const se importa mientras que, con la segunda, se importará la predeterminada.

Cerveza de jengibre
fuente
Me encanta tu respuesta, gracias!
White159
0

default es básicamente const someVariableName

No necesita un identificador con nombre porque es la exportación predeterminada para el archivo y puede defaultasignarle el nombre que desee cuando lo importe, por lo que solo se condensa la asignación de variables en una sola palabra clave.

Mani Gandham
fuente
-3

Para mí, esta es solo una de las muchas idiosincrasias (énfasis en el idio (t)) del mecanografiado que hace que las personas se quiten el pelo y maldigan a los desarrolladores. Tal vez podrían trabajar para generar mensajes de error más comprensibles.

Perro grande
fuente