Understanding JavaScript Import Statements: Named vs Default Exports Explained
Atharva
Posted on January 24, 2024
Howdy, JavaScript enthusiasts! So, you're on the Redux journey, all excited to conquer state management. But hold up – there's a little surprise. As a beginner navigating the wild lands of Redux, I stumbled upon a puzzling situation while linking my store to a slice reducer.
I was watching a tutorial to use Redux by creating a simple counter app as I am a beginner, In the tutorial, they exported the slice reducer as default, right there in the same file as the slice. Sounded simple enough, didn't it? But as I'll unfold in this tale, simplicity can sometimes be a tricky companion. Let's rewind to that moment when I ventured into the Redux wilderness, armed with curly braces and a little too much confidence. 🌿🗺️
So here I created a slice named "counterSlice" for my app which will update its value when the "increment" or **"decrement" **function is called, Here is the code for Slice:
Now Here I exported my counterSlice reducer as default and imported it in my Store file as :
Can you spot a mistake in this? Now as a beginner, I was not able to spot any mistake, I spent hours and hours finding a solution to solve this error :
Now I made 2 mistakes here :
The first mistake was a conceptual mistake, I thought that member "counter" would take the slice "counterSlice" as a value but instead, it takes the reducer of our slice as a value.
The second mistake was ...Man! That mistake was a headache it is what caused me hours of searching on Google and chatgpt. It was a basic silly mistake but for beginner like me, it was something new to learn.
The second mistake was I used curly braces in the import statement:
import {counterSlice} from "./Slices/CounterSlice";
But instead, I should've written it as :
import counterSlice from "./Slices/CounterSlice";
Now what difference do curly braces make?
Though they look like they don't make any difference (classic beginner mistake)....But actually, they do make a big difference. Curly braces are mostly used to import named exports and the import statement without curly braces is mostly used for default exports.
What are Named and Default Exports?
Named Exports: Named exports in JavaScript allow you to export multiple values from a module, and you can import them using the same names in other modules. Each value is given a name, and you can import only the ones you need in another module.
In short, Named exports are useful when you want to expose multiple functionalities or values from a module and allow more selective imports in other parts of your code. For example:
// Module.js
export const variable1 = "I am variable 1";
export const variable2 = "I am variable 2";
// AnotherFile.js
import { variable1, variable2 } from './Module';
console.log(variable1); // Outputs: I am variable 1
console.log(variable2); // Outputs: I am variable 2
In this example, variable1 and variable2 are named exports from the Module.js file. In AnotherFile.js, we use the same names to import and use that variable.
Default Exports: Default exports in JavaScript allow you to export a single value as the default export from a module. Unlike named exports, a default export doesn't have a specific name when imported into another module. You can choose any name you like when importing a default export.
In short, one module should have at most only one default export, and the default export doesn't have a specific name when imported into another module. therefore, we don't use curly braces for it. For Example:
// Module.js
const myVariable = "I am a default export";
export default myVariable;
// AnotherFile.js
import anyNameIWant from './Module';
console.log(anyNameIWant); // Outputs: I am a default export
In this example, myVariable is the default export from the Module.js file. When importing it into AnotherFile.js, we can choose any name we want for the imported variable (anyNameIWant in this case).
So now myVariable from Module.js can be used by alias anyNameIWant in my AnotherFile.js.
So now it would be clear that:
If we want to import an entity from a module by its real name or if we want to import multiple entities we should use named export and to import it use curly braces.
If we want to import just one entity from a module we can use default export and we can import it using any name we want (except keywords).
Now let's go back to my problem, now are you able to find the mistake and solve the mistake?
The mistake there was, that I was exporting my slice reducer by default export but was trying to import it using curly brace {counterSlice}. So my store is importing counterSlice from my slice instead of reducer which will give an error because the store wants the reducer of a slice and not the slice as a whole itself. It is importing counterSlice because curly braces will try to import an entity named counterSlice and not reducer as it is used for named export. So it will import entities by their specific name.
So we should try to import it in a way we import default export :
Is there a way to import multiple entities using default export?
Default export should only export one entity, but as we are programmers we can do anything, we can find our way from anything.
We can export multiple entities as default export by passing them as an object!
For example:
// module.js
const entity1 = /* ... */;
const entity2 = /* ... */;
export default {
entity1,
entity2,
};
// anotherFile.js
import myModule from './module';
console.log(myModule.entity1);
console.log(myModule.entity2);
So I hope you understand the importance of one single pair of curly braces in the import statement. And how it can cause you hours of searching. So all my friends who just started programming or have been programming for years, we will always make mistakes. How silly that mistake would be do not worry keep learning, there is always something new to learn and always keep basics in mind!
Posted on January 24, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 30, 2024