Por que o `Export Default Const` é inválido?

351

Vejo que o seguinte é bom:

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

No entanto, isso está incorreto:

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

No entanto, isso é bom:

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

Isso pode ser explicado, por que consté inválido com export default? É uma adição desnecessária e qualquer coisa declarada como export defaulté presumida const?

Kayote
fonte
11
esdiscuss.org/topic/…
Bergi 28/03
11
export default Tab = connect( mapState, mapDispatch )( Tabs );deveria ser export default connect( mapState, mapDispatch )( Tabs );. Você está exportando o resultado da chamada de função, não a variável Tab.
ThaJay
2
Uma const ou let é necessária (e relevante) no módulo de exportação, mas irrelevante no módulo de importação, onde o identificador importado é sempre somente leitura (não pode ser atribuído a). Isso ainda não explica por que a sintaxe de "padrão de exportação" difere de "exportação" não padrão.
Denis Howe

Respostas:

303

consté como let, é uma LexicalDeclaration ( VariableStatement, Declaration ) usada para definir um identificador no seu bloco.

Você está tentando misturar isso com a defaultpalavra - chave, que espera que um HoistableDeclaration, ClassDeclaration ou AssignmentExpression o siga.

Portanto, é um SyntaxError .


Se você deseja constalgo, é necessário fornecer o identificador e não usá-lo default.

exportpor si só aceita uma VariableStatement ou Declaration à sua direita.


AFAIK a exportação em si não deve adicionar nada ao seu escopo atual.


O seguinte é bomexport default Tab;

Tabse torna uma AssignmentExpression , pois recebe o nome padrão ?

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

Aqui Tab = connect( mapState, mapDispatch )( Tabs );está uma AssignmentExpression .

Paul S.
fonte
27
A resposta é como isso se tornou um erro. A questão ainda é por quê? A única razão pela qual evita o abuso de const dessa maneira: export padrão const a = 1, b = 3, c = 4;
Sergey Orlov
7
"AFAIK the export in itself should not add anything to your current scope"Isso não é tão preciso, porque export const a = 1contribui apara o seu contexto atual. E mesmo export defaultno caso de aulas, porque também export default class MyClass {}contribui MyClasspara o seu contexto atual.
Ernesto
4
A @SergeyOrlov concorda que isso explica como isso gera um erro, mas esclarece pouco o porquê disso ser necessário. Embora não tenha certeza de que esse seja o único motivo, você provavelmente deve publicá-lo como uma resposta separada, não como um comentário para este.
Herick 07/02
Se eu fizer o seguinte: let a; export default a;e atualizar a variável a quando ela já tiver sido importada para outro módulo, por que a variável padrão de exportação não é atualizada?
K - A toxicidade no SO está crescendo.
Meu entendimento é, para abreviar, você pode escrever const foo = function bar() {}e também const Foo = class Bar {}, mas não const foo = const bar = 1. O mesmo para export default, é como const foo =.
zetavg 24/03
47

Você também pode fazer algo assim se desejar exportar uma const / let padrão, em vez de

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

Você pode fazer algo assim, que eu não gosto pessoalmente.

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

Se o nome do componente for explicado no nome do arquivo MyComponent.js, apenas não o nomeie, mantém o código reduzido.

import React from 'react'

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

Atualização : como isso é identificado como desconhecido no rastreamento de pilha, não é recomendável

Kevin Danikowski
fonte
14
Você não teve problemas com o stacktraces? Para mim, está causando a exibição Unknownem todos os lugares onde é exportação padrão sem nome
Jurosh
2
Enquanto isso funciona, sem dúvida é algo que todo desenvolvedor de reação fora do desenvolvimento de aplicativos de brinquedos deve se esforçar para evitar a todo custo.
1 em
11
@ Lix Eu não conseguia entender por que se deve evitar o uso dessa sintaxe. Você poderia explicar ou compartilhar um link? Obrigado.
sudip 18/12/19
3
@sudip Criar um componente sem nome não é bom para o modelo e a renderização do componente reagir.
li x
11
Parece limpo, no entanto, também Dan Abramov sugere que devemos usar nomes de funções / const apropriados na declaração do componente: twitter.com/dan_abramov/status/1255229440860262400 ;) "- aparecerá como Anônimo nos rastreamentos de pilha - aparecerá como Desconhecido no DevTools - não será verificado pelas regras de fiapos específicas do React - não funcionará com alguns recursos como a atualização rápida "
Zoltan
9

A resposta de Paulo é a que você está procurando. No entanto, por uma questão prática, acho que você pode estar interessado no padrão que tenho usado em meus próprios aplicativos React + Redux.

Aqui está um exemplo simplificado de uma das minhas rotas, mostrando como você pode definir seu componente e exportá-lo como padrão com uma única instrução:

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: eu uso o termo "Cena" para o componente de nível superior de qualquer rota).

Espero que isto seja útil. Eu acho que é muito mais limpo do que o convencionalconnect( mapState, mapDispatch )( BareComponent )

Tom
fonte
Decoradores muito ruim não pode parecer para ser usado em um componente função
Eric Kim
@EricKim Bummer. Mas, vale lembrar que a especificação do decorador ainda não está finalizada. Talvez os componentes funcionais não possam ser decorados usando o decorador "herdado", mas não sei se isso se deve a uma limitação do design herdado ou porque a implementação de decoradores herdados é incompleta ou com bugs. FWIW: @connecté o único decorador que eu uso, eu o uso apenas com componentes conectados a um repositório redux, quase todos são uma "rota" e quase toda rota deve ter estado (e, portanto, não pode ser uma função pura) .
22418 Tom
8

A resposta compartilhada por Paulo é a melhor. Para expandir mais,

Pode haver apenas uma exportação padrão por arquivo. Considerando que pode haver mais de uma const exportações. A variável padrão pode ser importada com qualquer nome, enquanto a variável const pode ser importada com seu nome específico.

var message2 = 'Eu sou exportado';

exportar message2 padrão;

export const message = 'Eu também sou exportado'

No lado das importações, precisamos importá-lo assim:

import {message} de './test';

ou

importar mensagem de './test';

Com a primeira importação, a variável const é importada, enquanto, com a segunda, a padrão é importada.

Cerveja de gengibre
fonte
Ame sua resposta, obrigado!
White159
0

default é basicamente const someVariableName

Você não precisa de um identificador nomeado porque é a exportação padrão para o arquivo e pode nomeá-lo como quiser ao importá-lo; portanto, defaultestá apenas condensando a atribuição de variável em uma única palavra-chave.

Mani Gandham
fonte
-3

Para mim, essa é apenas uma das muitas idiossincrasias (ênfase no idiota (t)) do texto datilografado que faz com que as pessoas arrancem os cabelos e amaldiçoem os desenvolvedores. Talvez eles possam trabalhar com mensagens de erro mais compreensíveis.

Cachorro Grande
fonte