Modules - import and export
Split code across files with export and import, and learn the difference between named and default exports.
A real React app has dozens or hundreds of files: one for each component, plus files for data and helpers. Each file needs a way to share some of its code with other files and to use code from them. JavaScript modules are that way.
You have already seen import { books } from './books.js' in the last lesson. Now you will learn what it means.
Named exports
In JavaScript, every file is its own module. Anything you create inside it is private to that file unless you export it. Put the word export in front of a const or function to share it.
These are called named exports, because each one is exported under its own name. To import them, you list the names inside curly braces: import { books, countDone } from './books.js'. The names must match exactly.
The text after from is the path to the file. ./ means "in the same folder as this file". Paths to your own files always start with ./ or ../ (one folder up).
Default exports
A file can also have one default export. It is the file's main thing. You write export default in front of it.
There are two differences when importing a default export:
- There are no curly braces:
import formatBook from './formatBook.js'. - You choose the name. The importing file can call it anything.
import fmt from './formatBook.js'would also work.
Look at the last part of App.js: export default function App(). Every sandbox in this course works because the hidden entry file does import App from './App'. The App component is the default export of App.js.
Mixing both, and importing packages
A file can have one default export and any number of named exports. You import them in one line, default first:
import App, { books, countDone } from './App.js';Packages you installed with npm are imported by their package name, without ./. This is how every React file gets React's tools:
import { useState } from 'react';
import { createRoot } from 'react-dom/client';useState and createRoot are named exports of the react and react-dom/client packages. You saw createRoot in your Vite project's main.jsx, and you will meet useState on Day 3.
Deep diveWhich should I use, named or default?
Both are fine, and React projects use both. A common convention, and the one react.dev and Vite's starter use, is: one component per file, exported as the default, with the file named after the component (BookCard.jsx exports BookCard). Named exports are handy for files that share several things, like a data.js with several constants. Some teams prefer named exports everywhere so that names always match. Pick one style per project and stay consistent.
Split it into modules
All the code below is in App.js. Move shelf into shelf.js as a named export, and describe into describe.js as a default export. Then import both into App.js. The page should look the same when you are done.
Show solution
export const shelf = ['Dune', 'Emma', 'Beloved'];export default function describe(list) {
return `${list.length} books: ${list.join(', ')}`;
}import { shelf } from './shelf.js';
import describe from './describe.js';
console.log(describe(shelf));
export default function App() {
return <p>{describe(shelf)}</p>;
}shelf is a named export, so it is imported with braces. describe is a default export, so it is imported without them.
utils.js contains export function slugify() and export default function format(). Which import is correct?
Why does import { useState } from 'react' have no ./ in the path?
Day 1 progress
Array methods - map, filter and find
Transform, narrow down and search arrays with map, filter and find, the three methods React lists are built on.
What is React?
What React is, why it exists, and the two big ideas behind it - components, and describing the UI instead of changing the page step by step.