Чому "Експорт за замовчуванням 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.