I was going through React Navigation docs and I encountered something like this over there:
import Ionicons from 'react-native-vector-icons/Ionicons';
import { createBottomTabNavigator } from 'react-navigation';
export default createBottomTabNavigator(
{
Now, I am unable to comprehend what this line does:
export default createBottomTabNavigator(
I mean it definitely exports something but is it a function?
If yes, then shouldn't it be like:
export default function createBottomTabNavigator(
or According to ES6 something like this:
export default function createBottomTabNavigator = () =>{
The code is equivalent to
const MyBottomTabNavigator = createBottomTabNavigator( { /* ... */ });
export default MyBottomTabNavigator;
The function is called, an Object is returned. The Object is exported and used elsewhere.
Edit:
More example code in the same vein:
const rootOf2 = Math.sqrt(2.0);
export default rootOf2;
Answer given by Chris G is correct. I would also like to add that there is the difference between two ways you can export your variables or functions, by export and export default.
Imagine having variable in file const myVar = 'someValue';
If you export it from file just with export export { myVar } you would have to import it in the file where you would like to use your variable of function like this: import { myVar } from 'name-of-your-module';
In other case, where you export it with default export default myVar, you can import it without {} - like this: import myVar from 'name-of-your-module'
Export default serves to export a single value or to have a fallback value for our module.
Related
Is the JavaScript import statement only used to import frameworks, or can it be used to import other things? What other things can it be used to import?
You can import variables, objects and basically anything as long as it's JavaScript. Note that frameworks usually export an object.
// file.js
export const a = 30;
// default.js
const object = { a: (param) => doSomething(param), ... };
export default object;
// main.js
import { a } from "file.js"; // console.log(a) -> 30
import Whatever from "default.js"; // import and name the default export
If one file has an export default:
export default {
function,
function2
}
How can I import these two functions in a separate file? When I try restructuring it with
import { function, function2 } from 'path'
I get an error saying function is not exported from 'path'
Since it's a default export, you will have to do it like below
export default {
function1,
function2
}
import Path from 'path';
Path.function1();
Path.function2();
Look into this ressource.
Basically, you can achieve this, by writing:
export const myExport1 = function
export const myExport2 = function2
And then:
import { myExport1, myExport2} from 'path'
I have a class in JS file like:
class A {
contructor(){}
//logic
}
and in the same file I fave functions:
async function b(){}
and in the end I export class:
module.exports = A;
Can I export also function "b"?
you can do the following:
class A {}
export async function b() {}
export default A
Elaborating:
You can have multiple named exports for a module but only a single default export. Most people would say it's good to have a default export for a file and then export any other modules as named exports.
For your issue you can see above that you could have the default export of A and then also use b as a named export. This could then be imported elsewhere as so:
import A, { b } from '../foo';
You likely would see this style with most OSS for example:
import React, { Component, Fragment } from 'react';
The import outside of the {} is the default export and the imports inside the {} are the named exports.
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"
How can I export a stateless pure dumb component?
If I use class this works:
import React, { Component } from 'react';
export default class Header extends Component {
render(){
return <pre>Header</pre>
}
}
However if I use a pure function I cannot get it to work.
import React, { Component } from 'react';
export default const Header = () => {
return <pre>Header</pre>
}
Am I missing something basic?
ES6 doesn't allow export default const. You must declare the constant first then export it:
const Header = () => {
return <pre>Header</pre>
};
export default Header;
This constraint exists to avoid writting export default a, b, c; that is forbidden: only one variable can be exported as default
Just as a side note. You could technically export default without declaring a variable first.
export default () => (
<pre>Header</pre>
)
you can do it in two ways
const ComponentA = props => {
return <div>{props.header}</div>;
};
export default ComponentA;
2)
export const ComponentA = props => {
return <div>{props.header}</div>;
};
if we use default to export then we import like this
import ComponentA from '../shared/componentA'
if we don't use default to export then we import like this
import { ComponentA } from '../shared/componentA'
You can also use a function declaration instead of assignment:
export default function Header() {
return <pre>Header</pre>
}
In your example, you already use curly brackets and return so this is apparently matching with your needs with no compromise.