Чому "Експорт за замовчуванням Const" недійсний?


352

Я бачу, що таке добре:

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 (та відповідні), але не мають значення в модулі імпорту, де імпортований ідентифікатор завжди лише для читання (не може бути призначений). Це все ще не пояснює, чому синтаксис "експорту за замовчуванням" відрізняється від "експорту" за замовчуванням.
Деніс Хоу

Відповіді:


305

constце як let, це лексичне декларування ( VariableStatement, декларація) ) використовується для визначення ідентифікатора в вашому блоці.

Ви намагаєтесь змішати це з defaultключовим словом, яке очікує HoistableDeclaration, ClassDeclaration або AssignmentExpression .

Тому це SyntaxError .


Якщо ви хочете constщось, вам потрібно вказати ідентифікатор, а не використовувати default.

exportсама по собі приймає змінну державу або декларацію праворуч.


AFAIK сам експорт не повинен нічого додати до вашої нинішньої сфери.


Далі добреexport default Tab;

Tabстає AssignmentExpression, оскільки йому надано ім'я за замовчуванням ?

export default Tab = connect( mapState, mapDispatch )( Tabs ); добре

Ось Tab = connect( mapState, mapDispatch )( Tabs );це ВираженіеПрісваіваніе .


27
Відповідь - як це стає помилкою. Питання все ще чому? Одна з причин, що запобігає зловживанню const таким чином: експорт за замовчуванням const a = 1, b = 3, c = 4;
Сергій Орлов

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до вашого поточного контексту.
Ернесто

4
@SergeyOrlov погоджуються, що це пояснює, як це створює помилку, але проливає мало світла на те, чому це потрібно. Хоча я не впевнений, що це єдина причина, ви, ймовірно, повинні розміщувати це як окрему відповідь, а не коментар до цієї.
Герик

Якщо я роблю наступне: let a; export default 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усюди, де є неназваний експорт за замовчуванням
Джурош

2
Хоча це працює, без сумніву, це те, що кожен реагуючий розробник поза розробкою додатків для іграшок повинен прагнути уникати будь-якою ціною.
li x

1
@lix Я не міг зрозуміти, чому слід уникати використання цього синтаксису. Будь ласка, поясніть або поділіться посиланням? Дякую.
судіп

3
@sudip Створення компонента без імені не є корисним для моделі компонентів реагування та візуалізації.
li x

1
Однак виглядає чистим, також Дан Абрамов пропонує, що ми повинні використовувати належні імена функції / const у декларації компонентів: twitter.com/dan_abramov/status/1255229440860262400 ;) "- відображатиметься як Anonymous у слідах стека - відображатиметься як Unknown у DevTools - не перевірятиметься правилами вказівки, що стосуються реагування - не працюватиме з такими функціями, як Fast Refresh "
Zoltan

9

Відповідь Павла - та, яку ви шукаєте. Однак, на практиці, я думаю, що вам може бути цікавий шаблон, який я використовував у своїх власних програмах React + Redux.

Ось зведений приклад з одного з моїх маршрутів, який показує, як ви можете визначити свій компонент та експортувати його за замовчуванням за допомогою одного оператора:

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 )


Занадто погані декоратори не можуть бути використані на функціональній складовій
Ерік Кім

@EricKim Bummer. Але варто пам’ятати, що специфікація декораторів ще не остаточна. Можливо, функціональні компоненти не можуть бути декоровані за допомогою «застарілого» декоратора, але я не знаю, чи це пов’язано з обмеженням застарілого дизайну чи через те, що реалізація застарілих декораторів є неповною або невдалою. FWIW: @connectце єдиний декоратор, який я використовую, я використовую його лише з компонентами, приєднаними до магазину скорочення, майже кожен з них є "маршрутом", і майже кожен маршрут повинен мати стан (і тому не може бути чистою функцією) .
Том

8

Відповідь, яку поділив Павло, найкраща. Щоб розширити більше,

На файл може бути лише один експорт за замовчуванням. Тоді як експорт може бути більш ніж одним. Змінна за замовчуванням може бути імпортована з будь-яким ім'ям, тоді як змінна const може бути імпортована з її конкретним іменем.

var message2 = 'Мене експортує';

експорт повідомлення за замовчуванням2;

export const message = 'Я також експортуюсь "

Що стосується імпорту, нам потрібно імпортувати його так:

імпорт {message} з './test';

або

імпорт повідомлення з './test';

При першому імпорті імпортується змінна const, тоді як при другому - імпортується змінна.


0

default в основному const someVariableName

Вам не потрібен ідентифікований ідентифікатор, тому що це експорт файлу за замовчуванням, і ви можете називати його всім, що ви хочете, імпортуючи його, тому defaultце просто конденсує призначення змінної в одне ключове слово.


-3

Для мене це лише одна з багатьох ідіосинкратій (наголос на idio (t)) машинопису, яка змушує людей виривати волосся та проклинати розробників. Можливо, вони могли б працювати над зрозумілими повідомленнями про помилки.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.