Key Takeaways
- React components are reusable UI units that you can compose into larger interfaces.
- A function component receives one props object and returns content for React to render, usually JSX.
- Use createRoot for the client-rendered Vite example below; frameworks may manage their own entry points.
- Class components remain supported, but React recommends function components for new code.
React components let you define a piece of UI once and reuse it with different inputs. Start with a capitalized function, read its props, and return the UI you want React to display.
This walkthrough uses React 19 APIs in a client-rendered Vite app. If you already have that setup, skip the installation commands and replace the files shown below.
Set Up the Client Example
Use Node.js and npm with a Node.js release supported by the Vite getting-started guide. To create a JavaScript React project, run:
npm create vite@latest react-components -- --template react
cd react-components
npm installKeep the generated configuration files. You'll replace the project's root-level index.html and src/main.jsx; the generated App.jsx isn't used by this minimal example. For a broader setup walkthrough, see create a React app with Vite.
Creating Components With Functions
Replace src/main.jsx with this complete entry file:
import { createRoot } from 'react-dom/client';
function Greeting(props) {
return <h1>Hello, {props.name}</h1>;
}
const element = <Greeting name="Sam" />;
const container = document.getElementById('root');
if (!container) {
throw new Error('Missing the HTML element with id="root".');
}
const root = createRoot(container);
root.render(element);Greeting is the component definition. <Greeting name="Sam" /> creates a React element describing that component with a particular input; it isn't the browser DOM element itself.
A function component receives one props object, not a separate argument for each attribute. Here, name="Sam" supplies the name property, so props.name evaluates to the string "Sam". React's props guide explains this input model.
<Greeting name="Sam" />
|
v
props = { name: "Sam" }
|
v
<h1>Hello, Sam</h1> rendered inside #rootRead Props With Destructuring
You can replace only the Greeting function with this equivalent declaration:
// Replacement for Greeting in src/main.jsx.
function Greeting({ name }) {
return <h1>Hello, {name}</h1>;
}Destructuring extracts name from the same props object. It doesn't change how many arguments the component receives.
Props are read-only inputs: don't assign to them or mutate objects passed through them. Return UI based on those inputs; use state when the component needs its own changing data. For the distinction, see React props vs state.
Understand the JSX
JSX is the HTML-like syntax inside the JavaScript file. In JSX, curly braces introduce JavaScript expressions: {props.name} evaluates the property and includes its value in the heading.
Your project toolchain transforms JSX into JavaScript the browser can execute; browsers don't execute JSX directly as written. The Vite React template provides the needed setup. See React JSX syntax for more examples.
Update HTML and Run the App
Replace index.html in the project root—not inside src or public—with:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>React Components Example</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>The empty div is React's mounting container. Vite processes the module script pointing to /src/main.jsx, which contains the component and mounting code. The explicit container check gives you a useful error if the HTML ID and JavaScript lookup don't match.
Start the development server from the project directory:
npm run devOpen the local address printed in your terminal, rather than opening index.html directly from disk. You should see Hello, Sam. Vite's HTML entry-point documentation explains how the HTML file and source modules fit together.
What createRoot Does—and Doesn't Do
createRoot(container) creates a React root inside a browser DOM element; root.render(element) displays the supplied React content there. This is the current mounting pattern for a client-rendered app, not a general guarantee that your application will run faster.
Older examples may use ReactDOM.render. That API was removed in React 19, so don't copy it into this example. The React DOM reference lists the removed APIs.
Nest React Components to Build Larger UIs
Composition means rendering one component inside another. Add this App definition at the top level of src/main.jsx, after Greeting:
// Add alongside Greeting, not inside its function body.
function App() {
return (
<main>
<Greeting name="Sam" />
<p>Welcome back.</p>
</main>
);
}Then replace the existing element declaration with:
// Replace the existing element declaration in src/main.jsx.
const element = <App />;Leave the container check and root code unchanged. App is now the parent component and Greeting is its child. Nesting component usage—not component definitions—is how you grow a component tree while keeping each piece focused.
Creating Components With Classes
Class components are still supported, but React recommends functions for new code. You'll encounter classes when maintaining existing applications; this class-component reference documents their API.
To compare equivalent syntax, add the import below at the top of src/main.jsx and replace only the existing Greeting function with the class declaration. Keep App, the element declaration, and all mounting code unchanged:
// Add this import beside the existing createRoot import.
import { Component } from 'react';
// Replace only the Greeting function with this class.
class Greeting extends Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}The class extends React's Component, reads inputs through this.props, and returns UI from render(). It produces the same greeting without changing how its parent uses it. Hooks aren't supported inside class components.
Add State With a Hook
State is a component's memory between renders. To try it, remove the class example and its Component import, add the following import, and use this function as your Greeting definition:
// Add beside the existing createRoot import.
import { useState } from 'react';
// Replace the previous Greeting definition.
function Greeting({ name }) {
const [count, setCount] = useState(0);
function handleClick() {
setCount(previousCount => previousCount + 1);
}
return (
<>
<h1>Hello, {name}</h1>
<button type="button" onClick={handleClick}>
Greetings: {count}
</button>
</>
);
}useState(0) supplies the current count, initially zero, and a setter. Clicking the button queues an update calculated from the previous count, and React renders the updated UI. The <>...</> fragment groups the heading and button without adding a wrapper DOM element.
Hooks expose specific React capabilities: useState manages state, useContext reads context, useRef holds references, and useEffect synchronizes with external systems. Call Hooks such as useState at the top level of a function component or custom Hook—not inside a condition, loop, or event handler. Class components instead store state in this.state and update it with this.setState.
For an interactive next step, work through the React form example with useState.
Common Mistakes
- Lowercase component names: Use
<Greeting />, not<greeting />. JSX treats lowercase names as built-in tags. - Passing the definition instead of an element: Render
<Greeting name="Sam" />, not theGreetingfunction itself. - Changing props: Keep inputs read-only; update state or ask the parent to supply different props.
- Defining a child inside its parent: Declare components at the top level, then nest their JSX usage.
FAQ
How do you create a React component?
Define a JavaScript function whose name starts with a capital letter and return the UI it should display. Use it through JSX, such as <Greeting name="Sam" />, inside another component or at the app root.
What are props in React?
Props are read-only inputs supplied to a component through JSX attributes. A function component receives one props object; function Greeting({ name }) extracts its name property with JavaScript destructuring.
Do React components need to return JSX?
No. Components can return supported React nodes, including strings, numbers, arrays of nodes, or null to render nothing. JSX is a convenient way to describe React elements, not a required return format.
Are class components still supported in React?
Yes. React still supports class components, but recommends function components for new code. Functions can use Hooks; classes use APIs such as this.state and this.setState instead.
How do you render a React component with createRoot?
Import createRoot from react-dom/client, obtain an existing DOM container, create a root, and call its render method with a React element. For HTML already generated by React on the server, use hydrateRoot instead; a framework may handle this initialization for you.
Further Reading
- React: Your First Component — definitions, capitalization, and composition.
- React: Passing Props to a Component — inputs, destructuring, and read-only props.
- React: Writing Markup with JSX — JSX rules and fragments.
- React: createRoot — client roots, rendering, and hydration caveats.
- React: Component — supported class-component APIs.
- React: useState — state values, setters, and updater functions.
- React: Built-in Hooks — state, context, refs, effects, and other capabilities.
- Vite: Getting Started — prerequisites, scaffolding, and HTML entry points.
