Tại sao `Xuất mặc định Const` không hợp lệ?


351

Tôi thấy rằng sau đây là tốt:

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

Tuy nhiên, điều này không chính xác:

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

Tuy nhiên, điều này là tốt:

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

Điều này có thể được giải thích tại sao constkhông hợp lệ export default? Đây có phải là một bổ sung không cần thiết & bất cứ điều gì được tuyên bố là export defaultđược coi là constnhư vậy hay không?



1
export default Tab = connect( mapState, mapDispatch )( Tabs );nên export default connect( mapState, mapDispatch )( Tabs );. Bạn đang xuất kết quả của lệnh gọi hàm, không phải Tab biến.
ThaJay

2
Một const hoặc let được yêu cầu (và có liên quan) trong mô-đun xuất nhưng không liên quan trong mô-đun nhập, trong đó định danh đã nhập luôn ở chế độ chỉ đọc (không thể gán cho). Điều này vẫn không giải thích được tại sao cú pháp "xuất mặc định" khác với "xuất" không mặc định.
Denis Howe

Câu trả lời:


303

constgiống như let, nó là một LexicalDeclaration ( Var biếnStatement , Declaration ) được sử dụng để xác định một định danh trong khối của bạn.

Bạn đang cố gắng để kết hợp điều này với các defaulttừ khóa, mà hy vọng một HoistableDeclaration, ClassDeclaration hoặc AssignmentExpression theo nó.

Do đó, nó là một SyntaxError .


Nếu bạn muốn constmột cái gì đó bạn cần cung cấp định danh và không sử dụng default.

exporttự nó chấp nhận một Var biếnStatement hoặc Tuyên bố ở bên phải của nó.


Bản thân AFAIK không nên thêm bất cứ thứ gì vào phạm vi hiện tại của bạn.


Sau đây là tốtexport default Tab;

Tabtrở thành một AssignExpression vì nó được đặt tên mặc định ?

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

Đây Tab = connect( mapState, mapDispatch )( Tabs );là một AssignExpression .


27
Câu trả lời là làm thế nào nó trở thành một lỗi. Câu hỏi vẫn là tại sao? Một lý do nó ngăn chặn lạm dụng const theo cách này: xuất mặc định const a = 1, b = 3, c = 4;
Serge Orlov

7
"AFAIK the export in itself should not add anything to your current scope"Điều này không chính xác lắm, bởi vì export const a = 1thêm avào bối cảnh hiện tại của bạn. Và ngay cả export defaulttrong trường hợp của các lớp, bởi vì export default class MyClass {}thêm MyClassvào bối cảnh hiện tại của bạn.
Ernesto

4
@SergeyOrlov đồng ý rằng điều này giải thích cách điều này tạo ra lỗi, nhưng làm sáng tỏ một chút về lý do tại sao nó cần thiết. Mặc dù tôi không chắc đó là lý do duy nhất, nhưng có lẽ bạn nên đăng nó dưới dạng một câu trả lời riêng biệt, không phải là một bình luận cho câu hỏi này.
Herick

Nếu tôi làm như sau: let a; export default a;và sau đó cập nhật biến a khi nó đã được nhập vào mô-đun khác, tại sao biến mặc định xuất không cập nhật?
K - Độc tính trong SO đang tăng lên.

Hiểu biết của tôi là, ngắn gọn, bạn có thể viết const foo = function bar() {}và cũng có thể const Foo = class Bar {}, nhưng không const foo = const bar = 1. Tương tự như vậy export default, nó giống như const foo =.
zetavg

47

Bạn cũng có thể làm một cái gì đó như thế này nếu bạn muốn xuất mặc định một const / let, thay vì

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

Bạn có thể làm một cái gì đó như thế này, mà tôi không thích cá nhân.

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

19

Nếu tên thành phần được giải thích trong tên tệp MyComponent.js, chỉ cần không đặt tên thành phần, giữ cho mã mỏng.

import React from 'react'

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

Cập nhật : Vì nhãn này không xác định trong theo dõi ngăn xếp, nên không được đề xuất


14
Bạn không có vấn đề với stacktraces? Đối với tôi, nó gây ra hiển thị Unknownở mọi nơi nơi xuất khẩu mặc định không tên
Jurosh

2
Trong khi điều này hoạt động, không còn nghi ngờ gì nữa, đó là điều mà mọi nhà phát triển phản ứng ngoài phát triển ứng dụng đồ chơi nên cố gắng tránh bằng mọi giá.
li x

1
@lix Tôi không thể hiểu tại sao người ta nên tránh sử dụng cú pháp này. Bạn vui lòng giải thích hoặc chia sẻ một liên kết? Cảm ơn.
sudip

3
@sudip Tạo một thành phần không có tên là không tốt cho mô hình thành phần phản ứng và kết xuất.
li x

1
Tuy nhiên, trông có vẻ sạch sẽ, Dan Abramov gợi ý rằng chúng ta nên sử dụng tên / hàm đúng trong khai báo thành phần: twitter.com/dan_abramov/status/1255229440860262400 ;) "- sẽ hiển thị dưới dạng Ẩn danh trong dấu vết ngăn xếp - sẽ hiển thị dưới dạng Không xác định trong DevTools - sẽ không được kiểm tra theo quy tắc lint cụ thể của React - sẽ không hoạt động với một số tính năng như Làm mới nhanh "
Zoltan

9

Câu trả lời của Paul là người bạn đang tìm kiếm. Tuy nhiên, như một vấn đề thực tế, tôi nghĩ rằng bạn có thể quan tâm đến mẫu tôi đã sử dụng trong các ứng dụng React + Redux của riêng tôi.

Đây là một ví dụ rút gọn từ một trong các tuyến của tôi, cho thấy cách bạn có thể xác định thành phần của mình và xuất thành mặc định với một câu lệnh:

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

(Lưu ý: Tôi sử dụng thuật ngữ "Cảnh" cho thành phần cấp cao nhất của bất kỳ tuyến đường nào).

Tôi hy vọng điều này là hữu ích. Tôi nghĩ rằng nó trông gọn gàng hơn nhiều so với thông thườngconnect( mapState, mapDispatch )( BareComponent )


Các trang trí quá tệ dường như không thể được sử dụng trên một thành phần chức năng
Eric Kim

@EricKim Bummer. Nhưng, điều đáng ghi nhớ là thông số kỹ thuật trang trí chưa phải là cuối cùng. Có thể các thành phần chức năng không thể được trang trí bằng cách sử dụng trình trang trí "di sản", nhưng tôi không biết liệu đó có phải là do giới hạn của thiết kế cũ hay do việc triển khai các trang trí kế thừa không hoàn chỉnh hoặc có lỗi. FWIW: @connectlà công cụ trang trí duy nhất tôi sử dụng, tôi chỉ sử dụng nó với các thành phần được gắn vào cửa hàng redux, hầu hết mọi thứ trong số đó là một "tuyến đường" và hầu như mọi tuyến đường đều phải có trạng thái (và do đó không thể là một chức năng thuần túy) .
Tom

8

Câu trả lời được chia sẻ bởi Paul là câu trả lời hay nhất. Để mở rộng hơn,

Chỉ có thể xuất một mặc định cho mỗi tệp. Trong khi đó có thể có nhiều hơn một const xuất khẩu. Biến mặc định có thể được nhập với bất kỳ tên nào, trong khi đó biến const có thể được nhập với tên cụ thể của nó.

var message2 = 'Tôi đang xuất';

xuất thông báo mặc định2;

export const message = 'Tôi cũng đang xuất'

Ở phía nhập khẩu, chúng ta cần nhập nó như thế này:

nhập {tin nhắn} từ './test';

hoặc là

nhập tin nhắn từ './test';

Với lần nhập đầu tiên, biến const được nhập trong khi với biến thứ hai, biến mặc định sẽ được nhập.


Yêu câu trả lời của bạn, cảm ơn bạn!
White159

0

default về cơ bản là const someVariableName

Bạn không cần một mã định danh được đặt tên bởi vì đó là xuất mặc định cho tệp và bạn có thể đặt tên cho bất cứ thứ gì bạn muốn khi bạn nhập nó, vì vậy defaultchỉ cần cô đọng việc gán biến thành một từ khóa duy nhất.


-3

Đối với tôi đây chỉ là một trong nhiều điều bình dị (nhấn mạnh vào idio (t)) của bản thảo khiến mọi người phải nhổ tóc và nguyền rủa các nhà phát triển. Có lẽ họ có thể làm việc với các thông báo lỗi dễ hiểu hơn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.