Pourquoi `Export Export Const`` n'est pas valide?


351

Je vois que ce qui suit est bien:

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

Cependant, ceci est incorrect:

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

C'est pourtant bien:

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

Cela peut-il être expliqué s'il vous plaît pourquoi constest invalide avec export default? S'agit-il d'un ajout inutile et de tout ce qui est déclaré comme export defaultprésumé consttel ou tel?



1
export default Tab = connect( mapState, mapDispatch )( Tabs );devrait être export default connect( mapState, mapDispatch )( Tabs );. Vous exportez le résultat de l'appel de fonction, pas la variable Tab.
ThaJay

2
Un const ou let est requis (et pertinent) dans le module d'exportation mais non pertinent dans le module d'importation, où l'identifiant importé est toujours en lecture seule (ne peut pas être attribué à). Cela n'explique toujours pas pourquoi la syntaxe de "l'exportation par défaut" diffère de "l'exportation" non par défaut.
Denis Howe

Réponses:


303

constc'est comme let, c'est une LexicalDeclaration ( VariableStatement, Declaration ) utilisée pour définir un identifiant dans votre bloc.

Vous essayez de mélanger cela avec le defaultmot clé, qui attend une HoistableDeclaration, ClassDeclaration ou AssignmentExpression pour le suivre.

C'est donc un SyntaxError .


Si vous voulez constquelque chose, vous devez fournir l'identifiant et ne pas l'utiliser default.

exportaccepte par lui-même une déclaration ou une déclaration variable à sa droite.


AFAIK l'exportation en soi ne devrait rien ajouter à votre portée actuelle.


Ce qui suit est très bienexport default Tab;

Tabdevient un AssignmentExpression car on lui donne le nom par défaut ?

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

Voici Tab = connect( mapState, mapDispatch )( Tabs );une AssignmentExpression .


27
La réponse est de savoir comment c'est devenu une erreur. La question est toujours pourquoi? La seule raison pour laquelle il empêche l'abus de const de cette manière: exporte const const a = 1, b = 3, c = 4;
Sergey Orlov

7
"AFAIK the export in itself should not add anything to your current scope"Ce n'est pas si précis, car cela export const a = 1ajoute aà votre contexte actuel. Et même avec export defaulten cas de cours, car cela export default class MyClass {}s'ajoute également MyClassà votre contexte actuel.
Ernesto

4
@SergeyOrlov convient que cela explique comment cela génère une erreur, mais éclaire peu la raison pour laquelle cela est nécessaire. Bien que je ne sois pas sûr que ce soit la seule raison, vous devriez probablement poster cela comme une réponse distincte, pas un commentaire à celle-ci.
Herick

Si je fais ce qui suit: let a; export default a;puis mettre à jour la variable a alors qu'elle a déjà été importée dans un autre module, pourquoi la variable par défaut d'exportation ne se met-elle pas à jour?
K - La toxicité du SO augmente.

Ma compréhension est, pour faire court, vous pouvez écrire const foo = function bar() {}et aussi const Foo = class Bar {}, mais pas const foo = const bar = 1. Pareil pour export default, c'est comme const foo =.
zetavg

47

Vous pouvez également faire quelque chose comme ceci si vous souhaitez exporter par défaut un const / let, au lieu de

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

Vous pouvez faire quelque chose comme ça, que je n'aime pas personnellement.

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

19

Si le nom du composant est expliqué dans le nom du fichier MyComponent.js, ne nommez simplement pas le composant, le code reste mince.

import React from 'react'

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

Mise à jour : Étant donné que cela le marque comme inconnu dans le suivi de pile, il n'est pas recommandé


14
N'avez-vous pas eu de problèmes avec stacktraces? Pour moi, cela provoque l'affichage Unknownpartout où est l'exportation par défaut sans nom
Jurosh

2
Bien que cela fonctionne, c'est sans aucun doute quelque chose que tout développeur réactif en dehors du développement d'applications de jouets devrait s'efforcer d' éviter à tout prix.
li x

1
@lix Je ne comprenais pas pourquoi il fallait éviter d'utiliser cette syntaxe. Pourriez-vous expliquer ou partager un lien? Merci.
sudip

3
@sudip La création d'un composant sans nom n'est pas bonne pour le modèle de composant React et le rendu.
li x

1
Cela semble propre cependant, Dan Abramov suggère également que nous devrions utiliser les noms de fonction / const appropriés dans la déclaration de composant: twitter.com/dan_abramov/status/1255229440860262400 ;) "- apparaîtra comme anonyme dans les traces de pile - apparaîtra comme inconnu dans DevTools - ne sera pas vérifié par les règles spécifiques aux peluches de React - ne fonctionnera pas avec certaines fonctionnalités comme Fast Refresh "
Zoltan

9

La réponse de Paul est celle que vous recherchez. Cependant, en pratique, je pense que vous pouvez être intéressé par le modèle que j'utilise dans mes propres applications React + Redux.

Voici un exemple dépouillé de l'un de mes itinéraires, montrant comment vous pouvez définir votre composant et l'exporter par défaut avec une seule instruction:

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 { /* ... */ }

(Remarque: j'utilise le terme «scène» pour le composant de niveau supérieur de n'importe quel itinéraire).

J'espère que ceci est utile. Je pense que c'est beaucoup plus propre que le conventionnelconnect( mapState, mapDispatch )( BareComponent )


Dommage que les décorateurs ne semblent pas pouvoir être utilisés sur un composant fonctionnel
Eric Kim

@EricKim Bummer. Mais, il convient de garder à l'esprit que les spécifications du décorateur ne sont pas encore définitives. Peut-être que les composants fonctionnels ne peuvent pas être décorés à l'aide du décorateur "hérité", mais je ne sais pas si cela est dû à une limitation de la conception héritée, ou parce que l'implémentation des décorateurs hérités est incomplète ou boguée. FWIW: @connectest le seul décorateur que j'utilise, je ne l'utilise qu'avec des composants attachés à un magasin redux, presque chacun d'entre eux est une "route" et presque chaque route doit avoir un état (et ne peut donc pas être une fonction pure) .
Tom

8

La réponse partagée par Paul est la meilleure. Pour étendre davantage,

Il ne peut y avoir qu'une seule exportation par défaut par fichier. Alors qu'il peut y avoir plus d'une exportation const. La variable par défaut peut être importée avec n'importe quel nom, tandis que la variable const peut être importée avec son nom particulier.

var message2 = 'Je suis exporté';

exporter le message par défaut2;

export const message = 'Je suis également exporté'

Du côté des importations, nous devons l'importer comme ceci:

importer {message} depuis './test';

ou

importer un message depuis './test';

Avec la première importation, la variable const est importée tandis qu'avec la seconde, la variable par défaut sera importée.


Aimez votre réponse, merci!
White159

0

default est fondamentalement const someVariableName

Vous n'avez pas besoin d'un identifiant nommé, car il s'agit de l'exportation par défaut du fichier et vous pouvez le nommer comme vous le souhaitez lorsque vous l'importez, il defaultsuffit donc de condenser l'affectation des variables en un seul mot-clé.


-3

Pour moi, ce n'est là qu'une des nombreuses idiosyncrasies (l'accent sur l'idio (t)) de dactylographie qui oblige les gens à se coiffer et à maudire les développeurs. Peut-être qu'ils pourraient travailler à trouver des messages d'erreur plus compréhensibles.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.