`Export Default Const`が無効なのはなぜですか?


351

私は次のことが大丈夫だと思います:

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

ただし、これは正しくありません。

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

しかし、これは問題ありません。

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

これconstはなぜで無効なのか説明できますexport defaultか?それは不必要な追加であり、export default推定されたものは何constですか?



1
export default Tab = connect( mapState, mapDispatch )( Tabs );する必要がありますexport default connect( mapState, mapDispatch )( Tabs );。変数Tabではなく、関数呼び出しの結果をエクスポートしています。
ThaJay

2
constまたはletは、エクスポートモジュールでは必須(および関連)ですが、インポートモジュールでは無関係です。インポートモジュールでは、インポートされた識別子は常に読み取り専用です(割り当てられません)。これでも、「デフォルトのエクスポート」の構文がデフォルト以外の「エクスポート」と異なる理由はまだ説明されていません。
デニス・ハウ

回答:


303

const以下のようなものですletそれはLexicalDeclarationVariableStatement、宣言あなたのブロック内の識別子を定義するために使用されます)。

これを、HoistableDeclaration、ClassDeclaration、またはAssignmentExpressionが続くことを期待しているdefaultキーワードと混合しようとしています。

したがって、これはSyntaxErrorです。


const何かしたい場合は、識別子を提供し、使用しないでくださいdefault

exportそれ自体で、その右側のVariableStatementまたは宣言を受け入れます。


私の知る限り、エクスポート自体は現在のスコープに何も追加すべきではありません。


以下は結構ですexport default Tab;

Tabdefaultという名前が付けられると、AssignmentExpressionになります

export default Tab = connect( mapState, mapDispatch )( Tabs ); 結構です

これTab = connect( mapState, mapDispatch )( Tabs );AssignmentExpressionです。


27
答えはそれがエラーになる方法です。問題はまだなぜですか?この方法でconstの乱用を防ぐ1つの理由:export default const a = 1、b = 3、c = 4;
Sergey Orlov、2017年

7
"AFAIK the export in itself should not add anything to your current scope"現在のコンテキストにexport const a = 1追加さaれるため、これはそれほど正確ではありません。またexport default、クラスの場合でも、現在のコンテキストにexport default class MyClass {}追加さMyClassれるためです。
Ernesto

4
@SergeyOrlovは、これがどのようにエラーを生成するかを説明していることに同意しますが、なぜそれが必要なのかについてはほとんど明らかにしません。それが唯一の理由かどうかはわかりませんが、おそらくこれに対するコメントではなく、別の回答として投稿してください。
ヘリック2018

次のようにした場合:let a; export default a;変数aが既に別のモジュールにインポートされているときに変数aを更新すると、エクスポートのデフォルト変数が更新されないのはなぜですか?
K-SOの毒性が高まっています。

私の理解は、略して、あなたは書くことconst foo = function bar() {}もできますが、できconst Foo = class Bar {}ませんconst foo = const bar = 1。同じのためexport default、それだけのようですconst foo =
zetavg

47

代わりにデフォルトのconst / letをエクスポートしたい場合は、このようなこともできます

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

私が個人的に好きではないこのようなことをすることができます。

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

19

コンポーネント名がファイル名MyComponent.jsで説明されている場合は、コンポーネントに名前を付けないでください。コードがスリムになります。

import React from 'react'

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

更新:これはスタックトレースで不明としてラベル付けするため、お勧めしません


14
スタックトレースに問題がありませんでしたか?私にとってUnknownは、名前のないデフォルトのエクスポートがどこにでも表示される原因となっています
Jurosh

2
これは機能しますが、間違いなく、おもちゃのアプリケーション開発以外のすべての反応開発者は、あらゆるコストで回避しようと努力するべきものです。
li x

1
@lixなぜこの構文の使用を避けるべきなのか理解できませんでした。リンクを説明または共有していただけませんか?ありがとう。
Sudip

3
@sudip名前のないコンポーネントの作成は、reactコンポーネントモデルとレンダリングには適していません。
li x

1
しかし、またダンアブラモフ監督は、我々はコンポーネント宣言に適切な機能/ constの名前を使用する必要があることを示唆しているクリーンなルックス:twitter.com/dan_abramov/status/1255229440860262400は ;)「 -スタックトレースに匿名として表示されます-デベロッパーツールで不明として表示されます
Zoltan

9

ポールの答えはあなたが探しているものです。ただし、実際問題として、私が自分のReact + Reduxアプリで使用しているパターンに興味があると思います。

これは、私のルートの1つから取り除いた例で、コンポーネントを定義して、1つのステートメントでデフォルトとしてエクスポートする方法を示しています。

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

(注:ルートの最上位コンポーネントには「シーン」という用語を使用しています)。

これがお役に立てば幸いです。従来よりずっと綺麗に見えると思いますconnect( mapState, mapDispatch )( BareComponent )


デコレーターが機能コンポーネントで使用されているように見えない
Eric Kim

@EricKim Bummer。ただし、デコレータの仕様はまだ最終段階ではないことを覚えておいてください。「レガシー」デコレータを使用して機能コンポーネントを装飾できない場合がありますが、それがレガシーデザインの制限によるものか、レガシーデコレータの実装が不完全であるかバグがあるためかはわかりません。FWIW:@connect私が使用する唯一のデコレータです。reduxストアに接続されているコンポーネントでのみ使用します。それらのほとんどすべてが「ルート」であり、ほとんどすべてのルートに状態があるはずです(したがって、純粋な関数にはなりません) 。
トム・

8

パウロの答えは最高です。さらに拡大するには、

ファイルごとにデフォルトのエクスポートは1つだけです。一方、複数のconstエクスポートが存在する可能性があります。デフォルト変数は任意の名前でインポートできますが、const変数は特定の名前でインポートできます。

var message2 = 'エクスポートされました';

デフォルトのメッセージ2をエクスポートします。

constメッセージのエクスポート=「私もエクスポートされています」

インポート側では、次のようにインポートする必要があります。

'./test'から{メッセージ}をインポートします。

または

'./test'からメッセージをインポート;

最初のインポートではconst変数がインポートされますが、2番目のインポートではデフォルトの変数がインポートされます。


あなたの答えが大好きです、ありがとう!
White159

0

default 基本的に const someVariableName

名前付き識別子は必要ありません。ファイルのデフォルトのエクスポートであり、インポート時に任意の名前を付けることができるためdefault、変数の割り当てを1つのキーワードに圧縮するだけです。


-3

私にとって、これはtypescriptの多くの特異性(idio(t)に重点を置いている)の1つにすぎません。これにより、人々は髪を引っ張って開発者を呪います。多分彼らはより理解しやすいエラーメッセージを考え出すことに取り組むことができるでしょう。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.