Prefer default export eslint error - javascript

I am getting this eslint error:
Prefer default export
import React, { Component } from 'react';
class HomePage extends Component {
render() {
return (
<div className="Section">HomePage</div>
);
}
}
export { HomePage };
I have tried doing:
export { default as Homepage };
and then I get a fatal parsing error.
Then I changed it to:
export default HomePage;
Which clears the eslint error.
But then throws:
'./HomePage' does not contain an export named 'HomePage'.
Because I am calling HomePage like this:
import { HomePage } from './HomePage';
If I remove the brackets then I get this error:
"export 'default' (imported as 'HomePage') was not found in
'./HomePage'
import HomePage from './HomePage';
<PrivateRoute exact path="/" component={HomePage} />
What would be the proper way of changing this to the preferred default export?

From eslint-plugin-import
When there is only a single export from a module, prefer using default export over named export.
class HomePage extends Component {
//....
}
export default HomePage
In another file :
import HomePage from './Hello';
Check here codesandbox

Here's an example using functions:
function HomePage() {
function aHelperMethod() {
//
}
return {
aHelperMethod,
}
}
Now to import it in another file
import HomePage from './Hello';
And to use it you'll have to instantiate it
const homePage = HomePage()
homePage.aHelperFunction()

In some cases there should be more than one named export in the module.
export const foo = 'foo';
export const bar = 'bar';

Related

React JS: How can I export different components based on environment variable?

React JS code:
I want the src/app.jsx to do export default App when the REACT_APP_AUTH_SERVER variable in .env does not exist or have other value, and do export default withAuthenticator(App) when the REACT_APP_AUTH_SERVER variable in .env does exist, and has value aws-cognito:
src/app.jsx:
import React, { Component } from 'react';
import SecuredGate from './SecuredGate/SecuredGate';
import { withAuthenticator } from '#aws-amplify/ui-react'
import './App.css';
import '../fontStyles.css';
class App extends Component {
render() {
return (
<div>
<SecuredGate />
</div>
);
}
}
const Result = () => {
if (process.env.REACT_APP_AUTH_SERVER && process.env.REACT_APP_AUTH_SERVER === "aws-cognito"){
return withAuthenticator(App);
}
return App;
}
// export default App;
// export default withAuthenticator(App)
export default Result;
However, this is not working.
If I do:
export default App;
// export default withAuthenticator(App)
, it works, and if I do:
// export default App;
export default withAuthenticator(App)
it works as well.
So what am I missing?
I think the problem is that the Result component returns a component instead of an element. To understand this better look at what App component does when called with <App />. It runs the code in its body and returns some markup. But what happens if you call <Result />. It will run the code in its block and return another component (a function). So to solve this you can try:
const Result = (process.env.REACT_APP_AUTH_SERVER && process.env.REACT_APP_AUTH_SERVER === "aws-cognito")
? withAuthenticator(App)
: App;
}
export default Result;

Element type is invalid React Native

I have been having this error for hours and I don't know how to fix it, it's driving me crazy. In this shortcode here, I keep getting this error:
Element type is invalid: expected a string (for built-in components)
or a class/function (for composite components) but got: undefined. You
likely forgot to export your component from the file it's defined in,
or you might have mixed up default and named imports.
import * as Font from 'expo-font';
import React, {Component} from "react";
import { ActivityIndicator } from 'react-native'
import {Application} from "./src/Application.js";
class App extends Component {
constructor() {
super();
this.state = {
isReady: false,
};
}
componentWillMount = async() => {
await Font.loadAsync({
Roboto: require('./node_modules/native-base/Fonts/Roboto.ttf'),
Roboto_medium: require('./node_modules/native-base/Fonts/Roboto_medium.ttf')
});
this.setState({isReady: true,});
};
render() {
if (!this.state.isReady) {
return <ActivityIndicator />
}
return (
<Application/>
);
}
}
export default App;
The error pointed to _callee$ in 18:16, which is this line
this.setState({isReady: true,});
What could be causing this and a possible solution?
I tried importing import {Application} from "./src/Application.js" without {} before, but it also returned the error of
Check the render method of _default
Edited: Added "Application.js"
import React from 'react';
import Root from "native-base";
import { createAppContainer } from '#react-navigation/native';
import { createStackNavigator } from 'react-navigation-stack';
import { createDrawerNavigator } from 'react-navigation-drawer';
import Home from "./screens/home/index";
import Email from "./screens/email/index";
import ProfileScreen from "./screens/ProfileScreen";
import SideBar from "./screens/SideBar/SideBar";
const Drawer = createDrawerNavigator(
{
Home: { screen: Home},
//Email: { screen: Email},
ProfileScreen: { screen: ProfileScreen}
},
{
initialRouteName: "Home",
contentOptions: {
activeTintColor: "#e91e63"
},
contentComponent: props => <SideBar {...props}/>
}
);
const AppNavigator = createStackNavigator (
{
Drawer: {screen: Drawer}
},
{
initialRouteName: "Drawer",
headerMode: "none"
}
);
const AppContainer = createAppContainer(AppNavigator);
export default () =>
<Root>
<AppContainer/>
</Root>
With this statement,
export default () =>
<Root>
<AppContainer/>
</Root>
Without parentheses,it will interpreted as
export default () =>();
<Root>
<AppContainer/>
</Root>
So,it will return undefined which is not valid react element.Because of this above error will occur.
wrap the export default statement with ().It should be
export default () =>(
<Root> <AppContainer/></Root>
);
OR
export default () =>( <Root> <AppContainer/></Root> );
And import should be
import Application from "./src/Application";
Try
import * as Application from './src/application.js';
You are not exporting a named item but just a function byt you are trying to import a named item.
Check that you are exporting Application correctly from Application.js.
It should just be "export Application".
You are probably importing your components the wrong way.
How are you exporting Application in Application.js ?
Maybe remove {} will fix it
import Application from "./src/Application.js";
There is two ways you can export/import
export function ...
// another file
import {...} from '...'
Or using the default export
export default function ...
// another file
import ... from '...'
If you want to import it like
import {Application} from "./src/Application.js";
You should be exporting it like
export function Application...
And if you look ate what the error says...
...You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Export pure functional component without decorators

I'm trying to export a component without the decorators (connect() in this case)
for unit testing with jest.
So, how could I do this:
import React, { Component } from 'react';
import { connect } from 'react-redux';
export class Header extends Component {
render(){
return <pre>Header</pre>
}
}
export default connect()(Header);
With this component (the export at the beginning doesn't work, it stills exports the connected component)
export let Header = props => {
render(){
return <pre>Header</pre>
}
}
Header = connect()(Header);
export default Header;
Use different variable for your connected component as the following code:
export let Header = props => {
render(){
return <pre>Header</pre>
}
}
let HeaderConnected = connect()(Header);
export default HeaderConnected;
Now you can import your Header freely without using connect()
This can be done without even changing default export:
export let Header = props => {
render(){
return <pre>Header</pre>
}
}
export default connect()(Header);
There may be no need to export original component for connect alone because most well-designed HOCs expose original component:
import Header from '...';
const OriginalHeader = Header.WrappedComponent;

HOC import TypeError: Object(...) is not a function

I just tried to use a simple HOC with react.
Here is the function :
import React from "react"
const withOptions = (WrappedComponent) => {
return class extends React.Component {
render() {
return <WrappedComponent { ...this.props } />
}
}
}
export default withOptions
The problem seems to be in the way i export/import it.
Imported and used in a simple way, it works :
import withOptions from "./Options"
...
class BilanClimatique extends React.Component{
...
}
const StyledBilanClimatique = withStyles(styles)(BilanClimatique)
export default withOptions(StyledBilanClimatique)
But if i use an intermediate file like index.js
import withOptions from "./Options"
export {
withOptions
}
And import it in my component like that
import {
withOptions
} from "./index"
Here is what i get
Can someone help me understand this ?
EDIT :
I found that the component that is using the HOC is imported from the same file as the HOC :
import withOptions from "./Options"
import BilanClimatique from "./BilanClimatique"
export {
withOptions,
BilanClimatique
}
And that causes the problem, but I don't understand why...
Here is a sandbox with the problem https://codesandbox.io/s/r074735yvo
This seems to be a problem with hoisting of 'exports'. From what I can see, the imports get hoisted, but I could not see anything similar for exports.
The flow which causes problem (codesandbox):
App.js:
import { BilanClimatique } from "./components/index";
./components/index.js:
// just using the "re-export" shortcut
export { default as BilanClimatique } from "./BilanClimatique";
export { default as withOptions } from "./Options";
./components/BilanClimatique.js:
import { withOptions } from "./index";
./components/Options.js:
const withOptions = WrappedComponent => {
return ... //snipped code
export default withOptions;
When App.js asks index.js for BilanClimatique, it in turn asks the same index.js for withOptions. But since exports don't seem to be hoisted, index.js has not yet made withOptions available.
How to solve:
Ordered exports:
in ./components/index.js, change the order of exports as per your dependency:
// just using the "re-export" shortcut
export { default as withOptions } from "./Options";
export { default as BilanClimatique } from "./BilanClimatique";
I would not recommend it. It is very fragile.
Use index.js to only expose to outside your namespace. Inside your namespace, rely on explicit imports.
i.e. in ./components/BilanClimatique.js:
import withOptions from "./Options";
If you have a very large codebase, use multiple index.js for exporting your "contracts". Take a look at the codebases of various library authors, I think that is the strategy they take.
I would personally recommend #2 over #3 unless you run into problems with #2.
. doesn't look as a great import path. Try to import from 'index' file.
import {
Logo,
withOptions
} from "./index"

export default usage with deconstruct

I came to a codebase that did this
//index.js
export { default } from './Tabs'
export { default as Tab } from './Tab'
//Tab.js
export default class Tab extends Component {
render() => 'Something'
}
It's understandable that the author put Tab files under a Tab folder so that in other place he can just do import './Tabs' but why within the index.js he need to deconstruct?
Lots of people follow this nomenclature where the index file is just exports which then makes the imports easier.
It lets you import from the Tabs folder without explicitly saying the index.js filename. Most importantly it lets you import things from the folder Tab in just one statement.
For Example:
// Tab/Tab.js
import React, { Component } from "react";
class Tab extends Component {
render() {
return <span>Tab</span>;
}
}
export default Tab;
// Tab/Tabs.js
import React, { Component } from "react";
class Tabs extends Component {
render() {
return <span>Tabs</span>;
}
}
export default Tabs;
// Tab/index.js
export Tab from "./Tab";
export Tabs from "./Tabs";
// Main file
import React from "react";
import { render } from "react-dom";
import { Tab, Tabs } from "./Tab";
const App = () => (
<div>
<Tab />
<Tabs />
</div>
);
render(<App />, document.getElementById("root"));
demo: https://codesandbox.io/s/rr6klxj5j4
You can have a single default export from your file, Also writing
//index.js
export Tabs from './Tabs'
export Tab from './Tab'
will export them as a named export which you can later import as
import { Tabs, Tab } from './Tabs'
Also to understand the point default import is nothing different from an export named as default, so when you write
//index.js
export { default } from './Tabs' // Exports the Tabs as default
export { default as Tab } from './Tab' // imports the default from Tab and exports it as Tab
You could also write the above as
export { default } from './Tabs'
export Tab from './Tab'
In the above two cases you would import them as
import Tabs, { Tab } from './Tabs'
Check Error Exporting a component without importing for some more details

Categories