export default usage with deconstruct - javascript

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

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;

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;

Prefer default export eslint error

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';

Error import component

I have this error when i import my component
Module not found: Can't resolve '../src/components/Menu' in '/Users/userName/Documents/folder/repository/Project/src/pages/Home'
src
components
Menu
Menu.css
Menu.js
pages
Home.css
Home.js
Menu.js
import React, { Component } from 'react';
import './Menu.css';
class Menu extends Component {
render() {
return (
<div className="menu">
<h1>Je suis un Menu</h1>
</div>
);
}
}
export default Menu;
Home.js
import React, { Component } from 'react';
import './Home.css';
import Menu from './../components/Menu';
class Home extends Component {
constructor(props) {
super(props);
this.state = {
msg: 'Hello from the state of Home'
}
}
render() {
return (
<div className="home">
<h1 className="text">Welcome to the Home Page</h1>
<p>{this.state.msg}</p>
<Menu/>
</div>
);
}
}
export default Home;
You need to import from one level deeper:
import Menu from './../components/Menu/Menu';
You have a folder called Menu and the file you want is inside called Menu.js.
That's because '../src/components/Menu' doesn't point to your file.
Either use the path
'../src/components/Menu/Menu'
Or, if you want to use your original path, rename your Menu.js file to index.js.
In my experience the latter tends to be more popular due to it's inclusion in the hugely useful Airbnb JSX style guide.

How to Import and Export dynamically in ES6

In my react component directory, I setted index.js here.
import App from './App';
import Main from './Main/Main';
import Best from './Main/Best';
import Club from './Main/Club';
import Post from './Main/Post';
import Sidebar from './Sidebar/Sidebar';
export { App, Main, Best, Club, Post, Sidebar };
Usage in other js,
import {
App,
Main,
Best,
Club,
Post,
Sidebar
} from '../scripts/Containers/index';
But whenever I make component like that, should I have to write import / export statements index.js there?
Is there any magical way?
Please help me to solve out this problem!
Update (with #Bergi)
I modifed like this, and it works well.
export { default as App } from './App';
export { default as Header } from './Header/Header';
export { default as Main } from './Main/Main';
export { default as Best } from './Main/Best';
export { default as Club } from './Main/Club';
export { default as Post } from './Main/Post';
export { default as Sidebar } from './Sidebar/Sidebar';
But this didn't work
export * from './App';
export * from './Header/Header';
export * from './Main/Main';
export * from './Main/Best';
export * from './Main/Club';
export * from './Main/Post';
export * from './Sidebar/Sidebar';
In order to works with above code, I changed this in component
export default class Header extends Component {
constructor(...args) {
super(...args);
}
}
to
export class Header extends Component {
constructor(...args) {
super(...args);
}
}
I deleted export default module exports! And works second export way works(not first one)
Thanks #Bergi :)
But I think that dynamically import / export won't be able to use.
Maybe this is best way I think.

Categories