Import and Export React Components Like a Pro

Segun AjibolaSegun Ajibola
8 min read

React components often rely on one another to work well, thus developers use the import and export keyword often.

In this article, I will show you a better and cleaner way to import and export files in React.

Let's start with looking at how the export default keyword work.

Export Default

This is the default page.js in Next.js App Router.

// page.js

export default function Home() {
  return (
    <div>
      <h1>Hello World</h1>
    </div>
  );
}

Over the years, React default components have looked like this.

// App.js

function Home() {
  return (
    <div>
      <h1>Hello World</h1>
    </div>
  );
}

export default Home;

What's the difference between the two?

Both do the same thing. They render Hello World text to the screen.

The first example used export default function Home() while the second example used function Home() and added export default Home; after the end of the function.

In example 1, a function expression is used for the default export, while in example 2, a function declaration is used before the export statement.

Functionally, they are the same, but function expressions offer more flexibility.

Both examples work the same way when imported into other components. It is just a matter of personal preference or following a specific coding style guide.

Nesting Components in Same File

In a scenario where you want to create a Button component and use it in the main component of the same file.

Button component.

// Hero.jsx

function Button() {
    return (
      <button>Click</button>
)}

Here's how to use the Button component in the same file.

// Hero.jsx

function Button() {
   return (
    <button>Click</button>
)}

export default function Hero() {
  return (
    <div>
      <h1>Hello World</h1>
      <Button />
    </div>
  );
}

Note that I didn't add the export default to the Button component. You can't export two functions by default, you can only export one with export default.

You can also use arrow functions.

// Hero.jsx

const Button = () => {
   return (
    <button>Click</button>
)}

const Hero = () => {
  return (
    <div>
      <h1>Hello World</h1>
      <Button />
    </div>
  );
}

export default Hero;

For arrow function Hero, note that export default is removed and put at the end.

When using export default with a constant, the const declaration should be separate from the export default keyword.

The code below will throw an error.

// error

export default const Hero = () => {
  return (
    <div>
      <h1>Hello World</h1>
      <Button />
    </div>
  );
}

You have seen how to use a component in the main component of the same file and how to export components with the export default keyword.

Now, let us see how to export both components.

Exporting Both Components

// Hero.jsx

export const Button = () => {
   return (
    <button>Click</button>
)}

const Hero = () => {
  return (
    <div>
      <h1>Hello World</h1>
      <Button />
    </div>
  );
}

export default Hero;

You are exporting both component here. Note that we used export const Button and not export default const Button.

You can't use the export default keyword with const as mentioned earlier.

Although, you can export two functions from the same file but you can't have two default functions to export in the same file.

We can also export named export this way.

const Button = () => {
   return (
    <button>Click</button>
)}

const Hero = () => {
  return (
    <div>
      <h1>Hello World</h1>
      <Button />
    </div>
  );
}

export { Button }
export default Hero;

This just makes us write a bit more but still works.

Now, let's use these functions or components in another file by importing it

Importing Components

By convention, developers save component files in a components folder. The components folder is in the root folder of our project.

Let's import the Hero component to the app/page.js file.

// page.js

import Hero from "../components/Hero";

export default function Home() {
  return (
    <div>
      <h1>Home Page</h1>
      <Hero />
    </div>
  );
}

The Hero component will render in the Home component here.

What if we want to import the Button component separately?

import Hero from "../components/Hero";
import { Button } from "../components/Hero";

export default function Home() {
  return (
    <div>
      <h1>Home Page</h1>
      <Hero />
      <Button />
    </div>
  );
}

Hero function component was exported this way in the code below. It is a default export function.

const Hero = () => {
  return (
    ...
  );
}

export default Hero;

Button function component was exported this way in the code below. It is a named export.

export const Button = () => {
   return (
    <button>Click</button>
)}

That is the reason Button component was imported like this here:

import { Button } from "../components/Hero";

What if we want to import many component in our page.js.

Let's say we have Navbar, Hero, About and Footer components in the components folder and we want to use all of them in our page.js file.

I have created these components files in the components folder and input these text in them.

// Navbar.jsx

import React from 'react'

const Navbar = () => {
  return (
    <div>Navbar Component</div>
  )
}

export default Navbar

I did something similar for About and Footer components.

Importing Multiple Components

Importing multiple components can quickly make our code messy.

For example, here's how we would import those components normally.

// page.jss

import { Button } from "../components/Hero";
import Navbar from "../components/Navbar";
import Hero from "../components/Hero";
import About from "../components/About";
import Footer from "../components/Footer";

export default function Home() {
  return (
    <div>
      <Navbar />
      <Hero />
      <About />
      <Button />
      <Footer />
    </div>
  );
}

It worked.

But here's a way to make our page.js file cleaner.

Create an index.js folder in the components folder. Components folder should look like this now.

📂components

↪🗄 About.jsx

↪🗄Footer.jsx

↪🗄Hero.jsx

↪🗄Navbar.jsx

↪🗄index.js

index.js file should contain this.

// components/index.js

import { Button } from "../components/Hero";
import Navbar from "../components/Navbar";
import Hero from "../components/Hero";
import About from "../components/About";
import Footer from "../components/Footer";

export {
    Button,
    Navbar,
    Hero,
    About,
    Footer,
}

We are importing the components as usual, then exporting them in a object. Every key in the object is the corresponding component's name that we are importing.

These components can now be imported as a named export.

In our app/page.js file, here's an updated way to import them.

// page.js

import { Button, Navbar, Hero, About, Footer } from "../components"

export default function Home() {
  return (
    <div>
      <Navbar />
      <Hero />
      <About />
      <Button />
      <Footer />
    </div>
  );
}

In one line!

Notice that we are importing from "../components" and not "../components/index".

This way, by default, JavaScript will check for an index file in the folder and import it.

"../components" and "../components/index" will work the same way.

It still worked.

If you want to import only the Button elsewhere, you can do that.

// anotherFile.js

import { Button } from "../components"

You can import components as you need them.

// anotherFile.js

import { Navbar, Button, Footer } from "../components"

This approach is cleaner and makes all files easier to work with from the index.js file.

What if you want to rename components? It's possible.

Renaming Imports

You can rename components - both export default and named components. Here is an example.

// Hero.jsx

export const Button = () => {
   return (
    <button>Click</button>
)}

const Hero = () => {
  return (
    <div>
      <h1>Hello World</h1>
      <Button />
    </div>
  );
}

export default Hero;

Importing in page.js.

// page.js

import { Button as RenamedButton, Navbar, About, Footer } from "../components"
import RenamedHero from "../components/Hero"

export default function Home() {
  return (
    <div>
      <Navbar />
      <RenamedHero />
      <About />
      <RenamedButton />
      <Footer />
    </div>
  );
}

Note how we are importing named export Button component.

// Hero.jsx

export const Button = () => {
  return <button>Click</button>;
};

it is still in the { } bracket and the Button is still used to reference the new name.

// page.js

import { Button as RenamedButton, .... } from "../components/Hero"

We are exporting Hero by default in the Hero.jsx.

// Hero.jsx

const Hero = () => {
  return (
    <div>
      <h1>Hero Component</h1>
      <Button />
    </div>
  );
};

export default Hero;

So we can use any name directly in the import statement.

// page.js

import RenamedHero from "../components/Hero"

Conclusion

How you import your components depends on how you create them. Export default or named export. Add a { } to import a named export.

Having a single point of importing and exporting components in every folder of multiple files will make importing and exporting components easier for you and those who read your code.

Here is the GitHub repo to copy this code. Click here to clone it.

That will be all. Hope you found value here as you learn to build more projects effectively.

If you enjoyed this article and want to see more content related to JavaScript and Web development, then follow me here, Twitter (X) or connect on LinkedIn. I'd be happy to count you as one of my ever-growing group of awesome friends on the internet.

Join my WhatsApp community of 200+ developers learning and building cool projects.

If you also want to support me, you can buy a cup of coffee for me here.

Thanks && Bye. 👋

11
Subscribe to my newsletter

Read articles from Segun Ajibola directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Segun Ajibola
Segun Ajibola

I'm a front-end web developer, enjoys working with TailwindCSS and React. Love to contribute to Open Source and meet new people on Twitter.