Skip to content
React rc getting-started 3 min read

Your First Component

A React component is just a JavaScript function that returns markup. Components are the building blocks of every React app—you compose small, reusable pieces into a full interface. In this guide you’ll write a component from scratch, export it, render it from App, and feed it data through props.

What a component looks like

A function component is a plain function whose name starts with a capital letter and which returns JSX (the HTML-like syntax React uses to describe the UI). Create a new file src/Greeting.tsx:

function Greeting() {
  return <h1>Hello, React!</h1>;
}

export default Greeting;

That’s a complete, valid component. The function returns a single JSX element, and export default makes it available to other files. Nothing renders to the screen yet, though—a component only does something when you render it.

The capitalization rule is not optional. React uses the first letter to decide what a tag means: lowercase (<div>) is treated as a built-in HTML element, while capitalized (<Greeting />) is treated as your component. Name it greeting and React will look for an HTML tag called greeting, render nothing useful, and warn you.

Rendering it from App

Components become visible when another component renders them. The root of a Vite + React app is src/App.tsx. Import your component and use it like a custom HTML tag:

import Greeting from "./Greeting";

function App() {
  return (
    <main>
      <Greeting />
    </main>
  );
}

export default App;

App itself is already wired into the page by src/main.tsx, which mounts it onto the <div id="root"> in index.html. Save the file and the dev server updates instantly:

Output:

Hello, React!

You can render a component as many times as you like. React treats each <Greeting /> as an independent instance:

function App() {
  return (
    <main>
      <Greeting />
      <Greeting />
      <Greeting />
    </main>
  );
}

The one-root-element rule

A component’s return may only produce one top-level element. This is invalid—two sibling elements with no parent:

function Profile() {
  return (
    <h1>Ada Lovelace</h1>
    <p>Mathematician</p>   // ❌ Adjacent JSX elements must be wrapped
  );
}

Wrap them in a single parent. A <div> works, but when you don’t want an extra DOM node, use a Fragment—written as empty <>...</> tags—which groups children without rendering anything itself:

function Profile() {
  return (
    <>
      <h1>Ada Lovelace</h1>
      <p>Mathematician</p>
    </>
  );
}

Passing data with props

Hard-coded text isn’t reusable. Props (short for “properties”) are the inputs you pass to a component, exactly like HTML attributes. React collects them into a single object that becomes the function’s first argument. Destructure it to read individual values:

type GreetingProps = {
  name: string;
};

function Greeting({ name }: GreetingProps) {
  return <h1>Hello, {name}!</h1>;
}

export default Greeting;

The curly braces inside JSX—{name}—switch from markup back into JavaScript, so the prop’s value is inserted into the output. Now pass different data from App:

import Greeting from "./Greeting";

function App() {
  return (
    <main>
      <Greeting name="Ada" />
      <Greeting name="Grace" />
      <Greeting name="Linus" />
    </main>
  );
}

Output:

Hello, Ada!
Hello, Grace!
Hello, Linus!

One component definition, three different results. Props can be any type—strings, numbers, booleans, arrays, objects, even functions—and non-string values are passed inside braces: <Greeting count={3} active={true} />.

Props are read-only. A component must never modify the props it receives; treat the props object as immutable. When the UI needs to change over time in response to user actions, you reach for state instead, covered later in this section.

Best practices

  • Name every component with a capital letter (UserCard, not userCard) and match the file name to the component for easy navigation.
  • Keep components small and focused—one component, one job—then compose them together.
  • Use a Fragment (<>...</>) instead of a wrapper <div> when you only need to satisfy the single-root rule, to avoid polluting the DOM.
  • Destructure props in the function signature (function Greeting({ name })) so each input is named and visible at a glance.
  • Type your props with TypeScript so the editor flags missing or mismatched values before the app even runs.
  • Treat props as read-only; never assign to them inside the component.
Last updated June 14, 2026
Was this helpful?