'Why Is `Export Default Const` invalid?

I see that the following is fine:

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

However, this is incorrect:

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

Yet this is fine:

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

Can this be explained please why const is invalid with export default? Is it an unnecessary addition & anything declared as export default is presumed a const or such?



Solution 1:[1]

const is like let, it is a LexicalDeclaration (VariableStatement, Declaration) used to define an identifier in your block.

You are trying to mix this with the default keyword, which expects a HoistableDeclaration, ClassDeclaration or AssignmentExpression to follow it.

Therefore it is a SyntaxError.


If you want to const something you need to provide the identifier and not use default.

export by itself accepts a VariableStatement or Declaration to its right.


The following is fineexport default Tab;

Tab becomes an AssignmentExpression as it's given the name default ?

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

Here Tab = connect( mapState, mapDispatch )( Tabs ); is an AssignmentExpression.


Update: A different way to imagine the problem

If you're trying to conceptually understand this and the spec-reasoning above is not helping, think of it as "if default was a legal identifier and not a reserved token, what would be a different way to write export default Foo; and export default const Foo = 1; ?"

In this situation, the expanded way to write it would be

// pseudocode, this thought experiment is not valid JS

export default Foo;
// would be like
export const default = Foo;

export default const Foo = 1;
// would be like
export const default const Foo = 1;
// so would the following line make sense?
const bar const Foo = 1;

There is a valid argument the expansion should be something like

// pseudocode, this thought experiment is not valid JS

export default const Foo = 1;
// would be like
const Foo = 1;
export const default = Foo;

However, this then would become ambiguous per Sergey's comment, so it makes more sense to write this pattern explicitly instead.

Solution 2:[2]

You can also do something like this if you want to export default a const/let, instead of

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

You can do something like this, which I do not like personally.

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

Solution 3:[3]

If the component name is explained in the file name MyComponent.js, just don't name the component, keeps code slim.

import React from 'react'

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

Update: Since this labels it as unknown in stack tracing, it isn't recommended

Update 2: I have only been using the es5 version below since it keeps names on stack traces and react dev tools.

import React from 'react'

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

Solution 4:[4]

The answer shared by Paul is the best one. To expand more,

There can be only one default export per file. Whereas there can be more than one const exports. The default variable can be imported with any name, whereas const variable can be imported with it's particular name.

var message2 = 'I am exported';
export default message2;
export const message = 'I am also exported'

At the imports side we need to import it like this:

import { message } from './test';

or

import message from './test';

With the first import, the const variable is imported whereas, with the second one, the default one will be imported.

Solution 5:[5]

Paul's answer is the one you're looking for. However, as a practical matter, I think you may be interested in the pattern I've been using in my own React+Redux apps.

Here's a stripped-down example from one of my routes, showing how you can define your component and export it as default with a single statement:

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

(Note: I use the term "Scene" for the top-level component of any route).

I hope this is helpful. I think it's much cleaner-looking than the conventional connect( mapState, mapDispatch )( BareComponent )

Solution 6:[6]

default is basically const someVariableName

You don't need a named identifier because it's the default export for the file and you can name it whatever you want when you import it, so default is just condensing the variable assignment into a single keyword.

Solution 7:[7]

With export default, you don't export the name of, in this case, the variable.

wrong:

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

right:

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

You can import it on any name you like

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3
Solution 4 flaxel
Solution 5 Tom
Solution 6 Mani Gandham
Solution 7