ทำไม 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 );ควรจะเป็น คุณกำลังส่งออกผลลัพธ์ของการเรียกฟังก์ชันไม่ใช่แท็บตัวแปร
ThaJay

2
จำเป็นต้องใช้ const หรือ let (และที่เกี่ยวข้อง) ในโมดูลการส่งออก แต่ไม่เกี่ยวข้องในโมดูลการนำเข้าซึ่งตัวระบุที่นำเข้านั้นจะอ่านได้อย่างเดียวเสมอ (ไม่สามารถมอบหมายให้) สิ่งนี้ยังไม่ได้อธิบายว่าทำไมไวยากรณ์ของ "การส่งออกเริ่มต้น" แตกต่างจากการส่งออกที่ไม่ใช่ค่าเริ่มต้น
เดนิสฮาว

คำตอบ:


305

constเป็นเหมือนlet, มันเป็นLexicalDeclaration ( VariableStatement ประกาศ ) ใช้ในการกำหนดตัวบ่งชี้ในบล็อกของคุณ

คุณกำลังพยายามผสมสิ่งนี้กับdefaultคำหลักซึ่งคาดว่าHoistableDeclaration, ClassDeclarationหรือAssignment Expressionเพื่อติดตามมัน

ดังนั้นจึงเป็นSyntaxError


หากคุณต้องการสิ่งที่คุณต้องการที่จะให้ระบุและไม่ได้ใช้งานconstdefault

exportโดยตัวเองยอมรับVariableStatementหรือDeclarationไปทางขวา


AFAIK การส่งออกในตัวเองไม่ควรเพิ่มอะไรในขอบเขตปัจจุบันของคุณ


ต่อไปนี้เป็นเรื่องปกติexport default Tab;

Tabกลายเป็นAssignment Expressionตามที่ได้รับการตั้งค่า ชื่อหรือไม่

export default Tab = connect( mapState, mapDispatch )( Tabs ); ไม่เป็นไร

นี่Tab = connect( mapState, mapDispatch )( Tabs );เป็นAssignmentExpression


27
คำตอบคือมันกลายเป็นข้อผิดพลาดได้อย่างไร คำถามยังคงเป็นเพราะเหตุใด เหตุผลหนึ่งที่ป้องกันการใช้ const ในทางนี้: ส่งออก default const a = 1, b = 3, c = 4;
Sergey Orlov

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 ยอมรับว่าสิ่งนี้อธิบายว่าสิ่งนี้สร้างข้อผิดพลาดได้อย่างไร แต่ให้แสงสว่างเล็กน้อยว่าทำไมจึงจำเป็น แม้ว่าฉันไม่แน่ใจว่าเป็นเหตุผลเดียว แต่คุณควรโพสต์ข้อความนั้นเป็นคำตอบแยกต่างหากไม่ใช่แสดงความคิดเห็นกับสิ่งนี้
Herick

หากฉันทำสิ่งต่อไปนี้: 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 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 การสร้างคอมโพเนนต์ที่ไม่มีชื่อไม่ดีสำหรับโมเดลคอมโพเนนต์ที่ตอบสนองและการแสดงผล
li x

1
ดูสะอาด แต่ Dan Abramov ยังแนะนำว่าเราควรใช้ชื่อฟังก์ชั่น / const ที่เหมาะสมในการประกาศส่วนประกอบ: twitter.com/dan_abramov/status/1255229440860262400 ;) "- จะแสดงเป็น Anonymous ในร่องรอยสแต็ก - จะแสดงเป็น Unknown ใน DevTools - จะไม่ถูกตรวจสอบโดยกฎผ้าสำลีแบบตอบโต้เฉพาะ - จะไม่ทำงานกับคุณสมบัติบางอย่างเช่นการรีเฟรชอย่างรวดเร็ว "
Zoltan

9

คำตอบของ Paul คือคำตอบที่คุณกำลังมองหา อย่างไรก็ตามตามจริงฉันคิดว่าคุณอาจสนใจรูปแบบที่ฉันใช้ในแอป 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 )


นักตกแต่งที่เลวร้ายเกินไปดูเหมือนจะไม่สามารถใช้กับองค์ประกอบของฟังก์ชันได้
Eric Kim

@EricKim Bummer แต่มันก็ควรค่าแก่การจำไว้ว่า spec ของมัณฑนากรยังไม่จบ บางทีองค์ประกอบการใช้งานไม่สามารถตกแต่งโดยใช้มัณฑนากร "แบบดั้งเดิม" แต่ฉันไม่รู้ว่าเป็นเพราะข้อ จำกัด ของการออกแบบแบบดั้งเดิมหรือเนื่องจากการใช้งานตัวตกแต่งแบบดั้งเดิมนั้นไม่สมบูรณ์หรือมีบั๊ก FWIW: @connectเป็นมัณฑนากรคนเดียวที่ฉันใช้ฉันใช้เฉพาะกับส่วนประกอบที่ติดกับร้าน redux เกือบทุกอันนั้นเป็น "เส้นทาง" และเกือบทุกเส้นทางควรมีสถานะ (และไม่สามารถใช้งานได้อย่างบริสุทธิ์) .
Tom

8

คำตอบที่ Paul แบ่งปันให้นั้นเป็นคำตอบที่ดีที่สุด หากต้องการขยายเพิ่มเติม

สามารถส่งออกเริ่มต้นเพียงหนึ่งไฟล์ต่อหนึ่งไฟล์ ในขณะที่สามารถส่งออกได้มากกว่าหนึ่งรายการ ตัวแปรเริ่มต้นสามารถนำเข้าด้วยชื่อใด ๆ ในขณะที่ตัวแปร const สามารถนำเข้าด้วยชื่อเฉพาะ

var message2 = 'ฉันกำลังส่งออก';

ส่งออกข้อความเริ่มต้น 2;

ส่งออกข้อความ const = 'ฉันส่งออกด้วย'

ที่ด้านการนำเข้าเราจำเป็นต้องนำเข้าเช่นนี้:

นำเข้า {ข้อความ} จาก './test';

หรือ

นำเข้าข้อความจาก './test';

ด้วยการนำเข้าครั้งแรกตัวแปร const จะถูกนำเข้าในขณะที่อีกตัวหนึ่งจะนำเข้าตัวแปรเริ่มต้น


0

default เป็นพื้น const someVariableName

คุณไม่จำเป็นต้องใช้ตัวระบุชื่อเนื่องจากเป็นการส่งออกเริ่มต้นสำหรับไฟล์และคุณสามารถตั้งชื่อสิ่งที่คุณต้องการเมื่อคุณนำเข้าดังนั้นdefaultเพียงแค่รวมการมอบหมายตัวแปรไว้ในคำหลักเดียว


-3

สำหรับฉันนี่เป็นเพียงหนึ่งในหลายสำนวน (เน้นที่ idio (t)) ของ typescript ที่ทำให้คนดึงผมออกมาและสาปแช่งผู้พัฒนา บางทีพวกเขาอาจทำงานต่อไปด้วยข้อความแสดงข้อผิดพลาดที่เข้าใจได้มากขึ้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.