cf.completefrontend
Open lab My progress
THE REACT FIELD GUIDE

Your first component

Write a React component: a function that returns markup. Learn why its name needs a capital letter, nest components, and move them into their own files.

By the end, you can
  • 01
    Write a componentDefine a function with a capital letter that returns markup, export it, and avoid the bare return that makes it show nothing.
  • 02
    Nest componentsUse components inside other components, and say what the browser really receives: only the HTML tags they return.
  • 03
    Split components into filesMove a component into its own file and import it, with a default or a named export, and fix an import that doesn't match.

A piece of the page with a name

In Why React? you saw that React builds a page out of components: pieces like a header, a product card, or a cart. This lesson is about writing them. Here is the smallest component there is. Its result is live, under the code:

A welcome banner componentPop out in the code editor (opens in a new tab)JSX
export default function WelcomeBanner() {  return <h1>Welcome to the tea shop</h1>;}
ResultLoading…

Line 1 makes a function named WelcomeBanner. Line 2 is its only job: it returns <h1>Welcome to the tea shop</h1>, markup that looks like HTML, and React shows that heading on the page. That's all a component is: a JavaScript function that returns markup. Press Edit & run, change the words between <h1> and </h1>, and watch the heading follow as you type.

A function card, WelcomeBanner(), with an arrow to a card holding an h1 tag, the markup it returns. Another arrow leads to a page window showing the heading Welcome to the tea shop.WelcomeBanner()your component<h1>…</h1>the markup it returnspageWelcome to the tea shopwhat React shows
WelcomeBanner is a function. It returns markup, an <h1>, and React puts that heading on the page.

The markup inside a component is called JSX. It looks like HTML but it's part of your JavaScript; the next lesson, Writing markup with JSX, covers its rules. In this lesson, the JSX is plain tags like <h1>, <p>, and <article>.

Real-life analogyA rubber stamp

A shop owner carves a rubber stamp of the shop's logo once. After that, every bag, receipt, and loyalty card gets the logo with one press. If the logo changes, she carves a new stamp, and every new print changes with it.

In real life: Carving the stamp once
In React: Writing function TeaCard() { … } once
In real life: The name on its handle
In React: The component's name, starting with a capital letter
In real life: Pressing it on the paper, as often as you like
In React: Writing <TeaCard /> wherever you want a card
In real life: Only ink lands on the paper, never the stamp
In React: Only HTML tags reach the page, never the component
The main idea

A React component is a JavaScript function that returns markup. Its name starts with a capital letter, and you use it like a tag, <WelcomeBanner />, as many times as you like. React calls the function and puts the markup it returns on the page.

Writing a component, line by line

A real component usually returns more than one tag. Here is a card for one tea on a shop's menu. The example has two files, in tabs: App.jsx with the component, and styles.css, which draws the card's border.

A tea card componentPop out in the code editor (opens in a new tab)JSX
export default function TeaCard() {  return (    <article className="tea-card">      <h3>Green tea</h3>      <p>Fresh leaves from the hills.</p>      <p>$3</p>    </article>  );}
ResultLoading…

It has three parts, one per job:

  1. Export it. export default on line 1 is plain JavaScript, not React. It marks TeaCard as this file's main export, so another file can import it, and so the live result knows what to show.
  2. Define the function. function TeaCard() on line 1 is an ordinary function declaration. Its name starts with a capital letter; the next section shows why that matters.
  3. Return the markup. Lines 2 to 8 return one <article> holding a heading and two paragraphs (lines 3 to 7). className on line 3 is how JSX spells HTML's class; the next lesson explains why.

The round brackets on lines 2 and 8 matter. When the markup takes several lines, open a bracket on the same line as return. Here is what happens without one:

A card that never shows (a bug on purpose)Pop out in the code editor (opens in a new tab)JSX
function TeaCard() {  return    <article className="tea-card">      <h3>Green tea</h3>      <p>$3</p>    </article>;} export default function App() {  return (    <section>      <h2>Today's teas</h2>      <TeaCard />    </section>  );}
ResultLoading…

The result shows the heading from line 12, Today's teas, and no card. App (lines 9 to 16) uses TeaCard on line 13; the section after next explains how that works. The bug is on line 2: return stands alone. JavaScript ends a return statement at the end of its line when nothing follows it there (the semicolons lesson explains this rule), so TeaCard returns undefined and lines 3 to 6 never run. React shows nothing for a component that returns undefined, and no error tells you. Press Edit & run and change line 2 to return (, then add a line with ); after line 6, in place of its ;. The card appears.

A component can also be an arrow function stored in a constant. React treats it the same way. This course uses function declarations, as React's own documentation does:

The same card as an arrow functionJSX
const TeaCard = () => (
  <article className="tea-card">
    <h3>Green tea</h3>
  </article>
);

Line 1 stores the function in TeaCard. The brackets on lines 1 and 5 hold the markup the arrow function returns. It isn't exported, so this block has no result of its own.

Capital letters: your component or an HTML tag

React components must start with a capital letter. This is the rule beginners break most, so here is what happens when you don't follow it:

A component with a small first letter (a bug on purpose)Pop out in the code editor (opens in a new tab)JSX
function teaCard() {  return <p>Green tea, $3</p>;} export default function App() {  return (    <section>      <h2>Today's teas</h2>      <teaCard />    </section>  );}
ResultLoading…

Line 1 defines a function named teaCard, and line 9 uses <teaCard />. The result shows only the heading. Nothing crashed, but React never called teaCard. A tag that starts with a small letter is a tag name for the browser, like <section> or <h2>, even when a function by that name exists. So the page got an element called <teacard>: an unknown tag with nothing inside. Press Edit & run to see the console. React warns about line 9 twice:

  • <teaCard /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.
  • The tag <teaCard> is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.

PascalCase means every word starts with a capital letter, as in TeaCard and ShopHeader. React needs only the first letter to be a capital; the rest is a habit every React project shares. Fix the example: rename the function on line 1 to TeaCard and the tag on line 9 to <TeaCard />. The card appears, and the warnings go away.

Two rows. Top: the tag TeaCard with a capital T leads to the function TeaCard(), which leads to its article tags on the page. Bottom: the tag teaCard with a small t leads to the plain tag name teacard, which leads to an empty, unknown teacard element.<TeaCard />TeaCard()<article>…capital TReact calls your functionits tags reach the page<teaCard />"teacard"<teacard></teacard>small tonly a tag namean empty, unknown tag
With a capital letter, <TeaCard /> means your function, and React calls it. With a small letter, <teaCard /> is only a tag name, so the browser gets an empty <teacard>.

The reason is in how JSX works. Before your code runs, each tag becomes a function call that tells React what to make. For a tag with a small first letter, that call gets the tag's name as text, "section", and the browser makes the element. For a capital letter, it gets your function itself, TeaCard, and React calls it. The next lesson shows those calls, compiled by a real compiler.

How to read this table: each row is a tag you might write, what React takes it to mean, and what ends up on the page.

How React reads a tag name
When you writeReact reads it asWhat you get
<section>A small first letter: a tag name for the browser.The browser's own <section> element.
<TeaCard />A capital letter: the function named TeaCard in your code.React calls TeaCard, and its <article> goes on the page.
<teaCard />A small first letter: a tag name, even though your function has this name.An empty, unknown <teacard> element, and two warnings in the console.
<Teacard />A capital letter: a function named Teacard, which doesn't exist.An error, Teacard is not defined, because the name must match exactly.

Components inside components

Components get useful when they use each other. A menu page has a header and some tea cards. Each is its own component, and a third one, MenuPage, puts them together:

A menu page made of componentsPop out in the code editor (opens in a new tab)JSX
function ShopHeader() {  return (    <header>      <h1>Asha's Tea Shop</h1>    </header>  );} function TeaCard() {  return (    <article className="tea-card">      <h3>Green tea</h3>      <p>$3</p>    </article>  );} export default function MenuPage() {  return (    <main>      <ShopHeader />      <TeaCard />      <TeaCard />      <TeaCard />    </main>  );}
ResultLoading…

Lines 1 to 7 define ShopHeader, which returns a <header> with the shop's name. Lines 9 to 16 define TeaCard. MenuPage (lines 18 to 27) returns a <main> that uses <ShopHeader /> once, on line 21, and <TeaCard /> three times, on lines 22 to 24. The result shows the heading and three cards. They're all the same tea for now; the Passing props to a component lesson shows how to give each card its own.

MenuPage is the parent of ShopHeader and the cards, and they are its children. A tag like <TeaCard /> that has nothing inside it ends with />, which closes it. MenuPage is the one with export default, so it's the component this file gives to whoever imports it, and the one the live result shows. Press Edit & run and copy line 24 twice: five cards. Delete line 21: the header goes.

So what does the browser get? It never sees MenuPage or TeaCard: those are your functions. React calls each one, and only the HTML tags they return reach the page.

Left, what you wrote: a function card MenuPage with arrows down to ShopHeader and to TeaCard times 3. Right, what the browser gets: a window of HTML with main, a header, three article elements, and the closing main. No component names appear on the right.What you wroteMenuPageShopHeaderTeaCard × 3components: your functionsWhat the browser getspage HTML<main><header>…</header><article>…</article><article>…</article><article>…</article></main>
The menu page from the code above. You wrote components (left); the browser gets only the HTML tags they return (right): a <header> from ShopHeader and an <article> for each TeaCard.

Try it below. The buttons change how many cards MenuPage uses, and Use ShopHeader adds or removes ShopHeader. React renders the page right here, and the last box is the page's real HTML, read back from the page after every change.

Playground: what the browser sees
MenuPage with your choicesJSX
function ShopHeader() {  return (    <header>      <h1>Asha's Tea Shop</h1>    </header>  );} function TeaCard() {  return (    <article className="tea-card">      <h3>Green tea</h3>      <p>$3</p>    </article>  );} export default function MenuPage() {  return (    <main>      <ShopHeader />      <TeaCard />      <TeaCard />      <TeaCard />    </main>  );}
The page5 components

Asha's Tea Shop

Green tea

$3

Green tea

$3

Green tea

$3

What the browser seesHTML
 
Try it yourself

Choose how many TeaCards MenuPage uses, and whether it uses ShopHeader.

React renders these components on this page for real. The HTML is read from the page after each change: the same tags your browser's developer tools would show.

With three cards and the header, you used 5 components, and the HTML has 12 elements: <main>, the <header> and its <h1>, and an <article>, <h3>, and <p> for each card. Not one component name. Notice className became the HTML attribute class. Turn off Use ShopHeader, and the <header> and its <h1> leave the HTML.

One rule comes with nesting: use components inside other components, but always define them at the top level of the file, as in the menu page. Never write one function component inside another:

Don't define a component inside another (a mistake to avoid)JSX
export default function MenuPage() {
  // Don't: a new TeaCard function every time MenuPage runs
  function TeaCard() {
    return <article className="tea-card">Green tea</article>;
  }

  return <TeaCard />;
}

It looks tidy, and the page even looks right. But every time MenuPage runs, lines 3 to 5 make a brand-new TeaCard function. React compares components by the function itself, so it sees a different component every time: it removes that part of the page and builds it again from scratch, losing anything the card remembered, like text typed into a box. It's slow and causes bugs that are hard to find. The Preserving and resetting state lesson shows it happening. Keep TeaCard above MenuPage, as the menu page does.

Moving a component into its own file

One file with every component gets long. React projects usually give each bigger component its own file, named after it. Moving one takes three steps:

  1. Make a new file, such as TeaCard.jsx.
  2. Move the component there and export it.
  3. Import it in the file that uses it.

Here is the result. Click the tabs to read both files:

TeaCard in its own filePop out in the code editor (opens in a new tab)JSX
import TeaCard from "./TeaCard.jsx"; export default function App() {  return (    <main>      <h1>Asha's Tea Shop</h1>      <TeaCard />      <TeaCard />    </main>  );}
ResultLoading…

In TeaCard.jsx, line 1 exports the component with export default. In App.jsx, line 1 imports it: import TeaCard from "./TeaCard.jsx";. The ./ means "in the same folder as this file". Lines 7 and 8 use it twice, exactly as if it were written in App.jsx. Many projects leave off the .jsx, as in "./TeaCard"; their build tool finds the file either way.

Two editor windows. Left, TeaCard.jsx: export default function TeaCard. Right, App.jsx: import TeaCard from ./TeaCard.jsx, then the TeaCard tag. An arrow goes from the left window to the right one.TeaCard.jsxexport defaultfunction TeaCard(){ return … }1. export itApp.jsximport TeaCardfrom "./TeaCard.jsx";<TeaCard />2. import it, then use it
TeaCard.jsx exports its component, and App.jsx imports it by the file's name. Then <TeaCard /> works in App as if it were written there.

App.jsx is the root component file: the one at the top of the tree, holding the component that the whole page starts from. Every live example on this site has one more file that hands App to React, as you saw in Why React? (Pop out shows it). In a framework like Next.js, each page of the site has its own root component instead.

A file can also export more than one thing. JavaScript has two kinds of exports, which you met in The JavaScript you need for React: a default export, at most one per file, and named exports, as many as you like. Here Menu.jsx has both:

A default and a named export from one filePop out in the code editor (opens in a new tab)JSX
import Menu, { TeaCard } from "./Menu.jsx"; export default function App() {  return (    <main>      <h2>Today's pick</h2>      <TeaCard />      <Menu />    </main>  );}
ResultLoading…

In Menu.jsx, line 1 is a named export, export function TeaCard(), and line 10 is the default export, Menu. In App.jsx, line 1 imports both at once: Menu without braces for the default export, and { TeaCard } in braces for the named one. Line 7 shows one card as today's pick, and line 8 shows the whole menu.

How to read this table: each row asks the same question of both kinds of export.

Default or named exports
QuestionDefault exportNamed export
How do you export it?export default function TeaCard() {}export function TeaCard() {}
How do you import it?import TeaCard from "./TeaCard.jsx";import { TeaCard } from "./TeaCard.jsx";
How many can one file have?One at most.As many as you like.
Which name do you write on import?Any name; it gets the default export.The exact name it was exported with.
When do people use it?For the one main component of a file.When a file shares several components or values.

The import must match the export. Ask for a named export the file doesn't have, and the page can't start at all. Line 1 here uses braces, but TeaCard.jsx only has a default export:

Braces for a default export (an error on purpose)Pop out in the code editor (opens in a new tab)JSX
import { TeaCard } from "./TeaCard.jsx"; export default function App() {  return (    <main>      <h1>Asha's Tea Shop</h1>      <TeaCard />    </main>  );}
ResultLoading…

The result shows the browser's own error, SyntaxError, with the full address the preview gives the file: The requested module '…/TeaCard.jsx' does not provide an export named 'TeaCard'. The browser checks every import before any of the code runs, so nothing shows, not even the heading on line 6. Press Edit & run and remove the braces on line 1; the page comes back. Try every pairing in the playground below: it runs two small files as real modules in your browser.

Playground: match the import to the export
TeaCard.jsJavaScript
export default function TeaCard() {  return "Green tea";}
App.jsJavaScript
import TeaCard from "./TeaCard.js"; console.log(TeaCard());
Consolerunning

…

Try it yourself
TeaCard.js:
App.js:

Running the two files…

Both files run as real JavaScript modules in your browser, so the error is the browser's own. Reset goes back to a default export and an import without braces.

Matching pairs print Green tea. A default export with braces fails with does not provide an export named 'TeaCard', and a named export without braces fails with does not provide an export named 'default'. A common habit: a default export when a file has one main component, and named exports when it shares several. Whichever you choose, give the component a name. An unnamed one, like export default () => …, has no name of its own: error messages and React's developer tools show it as default or Anonymous, which makes bugs harder to find.

Splitting a real page into components

Real pages often start as one long component. This shop page works, but everything is in App: the header, two tea cards, and the footer.

A shop page in one componentPop out in the code editor (opens in a new tab)JSX
export default function App() {  return (    <main>      <header>        <h1>Asha's Tea Shop</h1>        <p>Open every day, 8 to 6</p>      </header>      <section>        <article className="tea-card">          <h3>Green tea</h3>          <p>$3</p>        </article>        <article className="tea-card">          <h3>Mint tea</h3>          <p>$4</p>        </article>      </section>      <footer>        <p>12 Park Street</p>      </footer>    </main>  );}
ResultLoading…

Lines 4 to 7 are the header, lines 8 to 17 a section with the two cards, and lines 18 to 20 the footer. To change how every card looks, you edit both copies. To use the header on a second page, you copy it. Look for parts with a name of their own, like "the header" or "the tea list", and make each one a component:

The same page, split into componentsPop out in the code editor (opens in a new tab)JSX
import ShopHeader from "./ShopHeader.jsx";import TeaList from "./TeaList.jsx";import ShopFooter from "./ShopFooter.jsx"; export default function App() {  return (    <main>      <ShopHeader />      <TeaList />      <ShopFooter />    </main>  );}
ResultLoading…

Now App.jsx reads like a table of contents: lines 1 to 3 import three components, and lines 8 to 10 put them in order. Each tab holds one of them. TeaList.jsx keeps two small components, GreenTea and MintTea, without exporting them: only TeaList uses them, so they stay in that file. The page looks the same, and the browser gets the same HTML. Open the ShopFooter.jsx tab in Edit & run and change the address: only the footer changes.

Your component, or a built-in tag?
  • <TeaCard />
  • <article>
  • <ShopHeader />
  • <header>
  • <button>
  • <SearchBox />
  • <img src="tea.png" />
  • <CartIcon />
Try it yourself
0 of 8 correct

Sort each tag: does React call a function you wrote, or does the browser make the element itself?

Choose a category for every card. You can change an answer at any time; Reset clears them all.

Common mix-ups

  • "A component is a special object that React makes." No. It's an ordinary JavaScript function that you write. React only calls it. (Older code also writes components as classes; React still runs them, but new code uses functions.)
  • "The browser sees my <TeaCard> tag." No. Component names never reach the page. The browser gets only the HTML tags your components return, as the playground shows.
  • "A small first letter is fine if the function exists." No. <teaCard /> is read as an HTML tag name, so React never calls your function and the page gets an empty <teacard>.
  • "A file can hold only one component." No. It can have one default export, any number of named exports, and components it keeps to itself, like GreenTea in TeaList.jsx.
  • "Every file with JSX needs import React from "react"." Not any more. Since React 17, the build adds what JSX needs by itself. You import from react only what you use by name, like useState. None of this lesson's files import React.
  • "Defining a component inside another keeps it private and tidy." No. It makes a new component every time the outer one runs, so React rebuilds it from scratch. Define components at the top level, and leave them unexported to keep them private.

Practice exercises

Each exercise shows its code's result under it, or when you press Edit & run. Change the code, and the result updates as you type. Try a guess first, then use the hints.

Exercise 1 · Warm-upCount the cards

How many tea cards does this page show? Answer first, then press Edit & run to check.

function TeaCard() {
  return (
    <article className="tea-card">
      <h3>Green tea</h3>
    </article>
  );
}

function TeaShelf() {
  return (
    <section>
      <TeaCard />
      <TeaCard />
    </section>
  );
}

export default function App() {
  return (
    <main>
      <TeaCard />
      <TeaShelf />
      <TeaCard />
    </main>
  );
}

Answer, then press Check. Spacing and letter case don’t matter.

    Exercise 2 · Warm-upBring back the cake card

    The page shows only the heading. Fix the component so the cake card appears. What does the card's heading say?

    function cakeCard() {  return (    <article className="tea-card">      <h3>Lemon cake</h3>      <p>$4</p>    </article>  );} export default function App() {  return (    <main>      <h2>Cakes</h2>      <cakeCard />    </main>  );}
    ResultLoading…

    Answer, then press Check. Spacing and letter case don’t matter.

      Exercise 3 · PracticeBring back the mint tea

      The tea card is missing, and there's no error. Find the bug and fix it. What does the card's heading say?

      function TeaCard() {  return    <article className="tea-card">      <h3>Mint tea</h3>      <p>$4</p>    </article>;} export default function App() {  return (    <main>      <h2>Today's teas</h2>      <TeaCard />    </main>  );}
      ResultLoading…

      Answer, then press Check. Spacing and letter case don’t matter.

        Exercise 4 · PracticeAdd a shop footer

        Write a ShopFooter component that shows Open every day, 8 to 6 in a <footer>, and use it under the card. What does the last line of the page say?

        function TeaCard() {  return (    <article className="tea-card">      <h3>Green tea</h3>      <p>$3</p>    </article>  );} export default function App() {  return (    <main>      <TeaCard />    </main>  );}
        ResultLoading…

        Answer, then press Check. Spacing and letter case don’t matter.

          Exercise 5 · ChallengeMove TeaCard into its own file

          Move TeaCard into the TeaCard.jsx tab with a default export, and import it in App.jsx. What line do you add at the top of App.jsx?

          function TeaCard() {  return (    <article className="tea-card">      <h3>Green tea</h3>      <p>$3</p>    </article>  );} export default function App() {  return (    <main>      <h1>Asha's Tea Shop</h1>      <TeaCard />    </main>  );}
          ResultLoading…

          Answer, then press Check. Spacing and letter case don’t matter.

            Exercise 6 · ChallengeFix the import

            Press Edit & run: this page shows an error instead of the shop. Fix line 1 of App.jsx without changing TeaCard.jsx. What should line 1 be?

            import TeaCard from "./TeaCard.jsx";
            
            export default function App() {
              return (
                <main>
                  <h1>Asha's Tea Shop</h1>
                  <TeaCard />
                </main>
              );
            }

            Answer, then press Check. Spacing and letter case don’t matter.

              Check your understanding

              For code questions, find each component first, then follow the tags from the exported one. Press Edit & run on a question's code to check your answer.

              The Your first component quiz · 8 questionsScore: first tries count
              1. Question 1 of 8What is a React component?

                Choose an answer to see the explanation.

              2. Question 2 of 8What does this shop page show?

                Read the code, then predictPop out in the code editor (opens in a new tab)JSX
                function TeaCard() {
                  return <article>Green tea</article>;
                }
                
                function ShopHeader() {
                  return <h1>Asha's Tea Shop</h1>;
                }
                
                export default function App() {
                  return (
                    <main>
                      <ShopHeader />
                      <TeaCard />
                      <TeaCard />
                      <TeaCard />
                    </main>
                  );
                }

                Choose an answer to see the explanation.

              3. Question 3 of 8Which of these functions can you use as a tag, like <…/>, in JSX?

                Choose an answer to see the explanation.

              4. Question 4 of 8What does this page show, with return alone on line 2?

                Read the code, then predictPop out in the code editor (opens in a new tab)JSX
                function Banner() {
                  return
                    <h1>Welcome to the tea shop</h1>;
                }
                
                export default function App() {
                  return (
                    <main>
                      <Banner />
                      <p>Open every day</p>
                    </main>
                  );
                }

                Choose an answer to see the explanation.

              5. Question 5 of 8MenuPage returns a <main> that uses <TeaCard />, and TeaCard returns an <article>. Which tags reach the browser's page?

                Choose an answer to see the explanation.

              6. Question 6 of 8SoldOutBadge.jsx holds this code. Which line imports it?

                Read the code, then predictJSX
                export function SoldOutBadge() {
                  return <span>Sold out</span>;
                }

                Choose an answer to see the explanation.

              7. Question 7 of 8How many default exports can one file have?

                Choose an answer to see the explanation.

              8. Question 8 of 8Why shouldn't you define one component inside another component's function?

                Choose an answer to see the explanation.

              Key takeaways

              • A React component is a JavaScript function that returns markup. You use it like a tag, as often as you like.
              • Its name must start with a capital letter. <TeaCard /> calls your function; <teaCard /> is only a tag name for the browser.
              • When the markup takes several lines, open a bracket on the return line. A bare return returns nothing.
              • Components use other components, forming a tree. The browser gets only the HTML tags they return, never their names.
              • Define every component at the top level of its file, never inside another component.
              • Move a component into its own file with export default and import X from "./X.jsx", or a named export and an import with braces. The import must match the export.

              Remember the one-liner.
              A component is a capitalized function that returns markup; write it once, use it like a tag anywhere.

              Coming next: Writing markup with JSX. It shows what each tag turns into, and why JSX has rules like one root element, closed tags, and className.

              CompleteFrontend Clear concepts. Working examples.