Mengapa `Ekspor Default Konstan` tidak valid?

351

Saya melihat bahwa yang berikut ini baik-baik saja:

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

Namun, ini tidak benar:

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

Namun ini baik-baik saja:

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

Bisakah ini dijelaskan, mengapa consttidak valid export default? Apakah ini merupakan tambahan yang tidak perlu & sesuatu yang dinyatakan sebagai export defaultdianggap constatau itu?

Kayote
sumber
1
export default Tab = connect( mapState, mapDispatch )( Tabs );seharusnya export default connect( mapState, mapDispatch )( Tabs );. Anda mengekspor hasil pemanggilan fungsi, bukan Tab variabel.
ThaJay
2
Konstanta atau let diperlukan (dan relevan) dalam modul ekspor tetapi tidak relevan dalam modul impor, di mana pengenal yang diimpor selalu hanya-baca (tidak dapat ditugaskan ke). Ini masih tidak menjelaskan mengapa sintaks "ekspor default" berbeda dari "ekspor" non-standar.
Denis Howe

Jawaban:

303

constseperti let, itu adalah LexicalDeclaration ( VariableStatement, Declaration ) yang digunakan untuk mendefinisikan pengidentifikasi di blok Anda.

Anda mencoba mencampur ini dengan defaultkata kunci, yang mengharapkan HoistableDeclaration, ClassDeclaration atau AssignmentExpression untuk mengikutinya.

Karena itu, ini adalah SyntaxError .


Jika Anda ingin constsesuatu, Anda harus memberikan pengenal dan tidak digunakan default.

exportdengan sendirinya menerima VariableStatement atau Deklarasi di sebelah kanannya.


AFAIK ekspor itu sendiri tidak boleh menambahkan apa pun ke ruang lingkup Anda saat ini.


Berikut ini baik-baik sajaexport default Tab;

Tabmenjadi AssignmentExpression karena diberi nama default ?

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

Berikut Tab = connect( mapState, mapDispatch )( Tabs );adalah Tugas Penugasan .

Paul S.
sumber
27
Jawabannya adalah bagaimana ini menjadi kesalahan. Pertanyaannya masih mengapa? Salah satu alasannya mencegah penyalahgunaan const dengan cara ini: ekspor default const a = 1, b = 3, c = 4;
Sergey Orlov
7
"AFAIK the export in itself should not add anything to your current scope"Ini tidak begitu akurat, karena export const a = 1menambah akonteks Anda saat ini. Dan bahkan dengan export defaultdalam kasus kelas, karena export default class MyClass {}menambah MyClasskonteks Anda saat ini juga.
Ernesto
4
@SergeyOrlov setuju bahwa ini menjelaskan bagaimana ini menghasilkan kesalahan, tetapi sedikit menjelaskan mengapa itu perlu. Meskipun saya tidak yakin itu satu-satunya alasan, Anda mungkin harus mempostingnya sebagai jawaban terpisah, bukan komentar untuk yang satu ini.
Herick
Jika saya melakukan hal berikut: let a; export default a;dan kemudian memperbarui variabel ketika sudah diimpor ke modul lain, mengapa variabel ekspor standar tidak diperbarui?
K - Keracunan dalam SO tumbuh.
Pemahaman saya adalah, singkatnya, Anda dapat menulis const foo = function bar() {}dan juga const Foo = class Bar {}, tetapi tidak const foo = const bar = 1. Sama export defaulthalnya, sama seperti const foo =.
zetavg
47

Anda juga dapat melakukan sesuatu seperti ini jika Anda ingin mengekspor default / let, alih-alih

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

Anda dapat melakukan sesuatu seperti ini, yang saya tidak suka secara pribadi.

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

Jika nama komponen dijelaskan dalam nama file MyComponent.js, jangan beri nama komponen, jaga agar kode tetap ramping.

import React from 'react'

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

Pembaruan : Karena ini label sebagai tidak dikenal dalam pelacakan tumpukan, itu tidak dianjurkan

Kevin Danikowski
sumber
14
Apakah Anda tidak memiliki masalah dengan stacktraces? Bagi saya itu menyebabkan tampilan di Unknownmana - mana di mana ekspor default tidak disebutkan namanya
Jurosh
2
Meskipun ini bekerja, tanpa diragukan lagi itu adalah sesuatu yang setiap pengembang bereaksi di luar pengembangan aplikasi mainan harus berusaha untuk menghindari dengan cara apa pun.
li x
1
@lix Saya tidak bisa mengerti mengapa orang harus menghindari menggunakan sintaks ini. Tolong jelaskan atau bagikan tautan? Terima kasih.
sudip
3
@sudip Membuat komponen tanpa nama tidak baik untuk model komponen rendering dan rendering.
li x
1
Terlihat bersih namun, Dan Dan Abramov menyarankan bahwa kita harus menggunakan nama fungsi / const yang tepat dalam deklarasi komponen: twitter.com/dan_abramov/status/1255229440860262400 ;) "- akan ditampilkan sebagai Anonim di jejak tumpukan - akan muncul sebagai Tidak Dikenal di DevTools - tidak akan diperiksa oleh aturan serat spesifik React - tidak akan berfungsi dengan beberapa fitur seperti Fast Refresh "
Zoltan
9

Jawaban Paul adalah yang Anda cari. Namun, secara praktis, saya pikir Anda mungkin tertarik dengan pola yang saya gunakan di aplikasi React + Redux saya sendiri.

Berikut ini adalah contoh sederhana dari salah satu rute saya, yang menunjukkan bagaimana Anda dapat mendefinisikan komponen Anda dan mengekspornya sebagai default dengan satu pernyataan:

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

(Catatan: Saya menggunakan istilah "Adegan" untuk komponen tingkat atas dari rute apa pun).

Saya harap ini bermanfaat. Saya pikir ini jauh lebih bersih daripada yang konvensionalconnect( mapState, mapDispatch )( BareComponent )

Tom
sumber
Dekorator yang terlalu buruk tampaknya tidak dapat digunakan pada komponen fungsi
Eric Kim
@EricKim Bummer. Tapi, perlu diingat bahwa spek dekorator belum final. Mungkin komponen fungsional tidak dapat didekorasi menggunakan dekorator "legacy", tetapi saya tidak tahu apakah itu karena keterbatasan desain legacy, atau karena penerapan dekorator lawas tidak lengkap atau bermasalah. FWIW: @connectadalah satu-satunya dekorator yang saya gunakan, saya hanya menggunakannya dengan komponen yang melekat pada toko redux, hampir setiap dari mereka adalah "rute," dan hampir setiap rute harus memiliki status (dan karena itu tidak dapat menjadi fungsi murni) .
Tom
8

Jawaban yang dibagikan oleh Paul adalah yang terbaik. Untuk memperluas lebih lanjut,

Hanya ada satu ekspor standar per file. Padahal bisa ada lebih dari satu ekspor const. Variabel default dapat diimpor dengan nama apa pun, sedangkan variabel const dapat diimpor dengan nama tertentu itu.

var message2 = 'Saya diekspor';

ekspor pesan default2;

export const message = 'Saya juga diekspor'

Di sisi impor kita perlu mengimpornya seperti ini:

impor {message} dari './test';

atau

impor pesan dari './test';

Dengan impor pertama, variabel const diimpor sedangkan, dengan yang kedua, yang default akan diimpor.

Bir jahe
sumber
Cintai jawaban Anda, terima kasih!
White159
0

default pada dasarnya const someVariableName

Anda tidak memerlukan pengenal yang dinamai karena ini adalah ekspor default untuk file tersebut dan Anda dapat menamainya apa pun yang Anda inginkan ketika Anda mengimpornya, jadi defaulthanya mengkondensasi penugasan variabel menjadi satu kata kunci tunggal.

Mani Gandham
sumber
-3

Bagi saya ini hanyalah salah satu dari banyak keanehan (penekanan pada idio (t)) naskah yang menyebabkan orang menarik rambut mereka dan mengutuk pengembang. Mungkin mereka bisa bekerja dengan membuat pesan kesalahan yang lebih dimengerti.

Anjing besar
sumber