React Component Anatomy: Structure and JSX Guide
A React component is built from three core parts: import statements, a function definition containing logic, and an export. This structure makes components reusable, maintainable building blocks for user interfaces. Understanding component anatomy is the foundation for effective React development.
What Is a React Component?
A React component is a reusable piece of user interface code that returns JSX (JavaScript XML). A functional component is a JavaScript function that accepts props and returns JSX describing what should appear on screen. Unlike class components, functional components have become the modern standard since React Hooks were introduced in version 16.8 (React, 2019).
The three essential parts of every functional component are:
- The Import — import React and any dependencies
- The Function Definition — write logic and return JSX
- The Export — make the component available elsewhere in your app
Let's examine each part with a complete, runnable example.
Core Structure: The Three Parts of a Component
A React component always follows a predictable pattern. Understanding this pattern makes it easier to read, debug, and extend components across your entire application.
import React from 'react';
const UserProfile = (props) => {
// 1. Logic can go here
const { name, age, location } = props;
const canVote = age >= 18;
// 2. The return statement with JSX
return (
<div>
<h2>{name}</h2>
<p>Age: {age}</p>
<p>Location: {location}</p>
<p>Can vote: {canVote ? 'Yes' : 'No'}</p>
</div>
);
};
export default UserProfile;
Step-by-Step Code Breakdown:
-
const UserProfile = (props) => { ... }: This is the function declaration.UserProfile: The name of the component. Crucially, component names must start with a capital letter. This is how React distinguishes between a regular HTML tag (like<div>) and a custom component (like<UserProfile />).(props): This is the single argument the function receives.props(short for properties) is an object containing all the data passed to this component from its parent.
-
Component Logic: Inside the function, before the
returnstatement, you can write any JavaScript logic you need. In this example, we are:- Destructuring the
propsobject to getname,age, andlocation. - Calculating a new variable,
canVote, based on theageprop.
- Destructuring the
-
The
returnStatement: This is what the component renders to the screen.- It must return a single root element. This is why we wrap everything in a
<div>. Alternatively, you could use a React Fragment (<>...</>) if you don't want to add an extra node to the DOM. - The content inside the
returnis JSX (JavaScript XML), which looks like HTML but allows you to embed JavaScript expressions inside curly braces{}.
- It must return a single root element. This is why we wrap everything in a
Understanding JSX: Markup Inside JavaScript
JSX is a syntax extension for JavaScript that allows you to write HTML-like code in your JavaScript files. It's one of the most powerful features of React because it makes UI code declarative and readable.
Key Features of JSX:
- Expressions in Curly Braces: You can embed any valid JavaScript expression inside
{}. In ourUserProfileexample, we used it to display the values ofname,age,location, and the result of the ternary operator forcanVote. - Attributes: JSX attributes are similar to HTML attributes, but they are written in camelCase. For example, the HTML
classattribute becomesclassNamein JSX, andforbecomeshtmlFor. This is becauseclassandforare reserved keywords in JavaScript. - Self-Closing Tags: All tags must be closed. For tags that don't have children, like
<img>or<input>, you must close them with a/, like<img />or<input />.
The JSX compiler (Babel) transforms this JSX into regular JavaScript function calls:
// This JSX...
<h2>{name}</h2>
// Transforms into this JavaScript:
React.createElement('h2', null, name)
Component Nesting and Composition
The true power of components comes from composition: building complex UIs by nesting components inside other components. This pattern allows you to reuse components multiple times with different props, creating a scalable architecture.
import React from 'react';
import UserProfile from './components/UserProfile';
function App() {
return (
<div>
<h1>User Profiles</h1>
<UserProfile name="Alice" age={30} location="New York" />
<UserProfile name="Bob" age={17} location="London" />
</div>
);
}
export default App;
In this App component, we are using our UserProfile component twice, passing different props to each one. This demonstrates the reusability and composability of components—the foundation of scalable React applications.
Best Practices for Component Structure
Following these patterns will make your components cleaner, more maintainable, and easier to test.
- Capitalize Component Names: Always start your component names with a capital letter. React uses this convention to identify components. For example,
UserProfileis a component, butuserProfileis a regular variable. - One Component Per File: It's a good practice to have one component per file, and the filename should match the component name (e.g.,
UserProfile.jsx). This makes it easy to locate components and prevents file bloat. - Destructure Props: Destructuring props at the beginning of your component makes the code cleaner and easier to read. Compare
const { name, age } = props;with repeatedly accessingprops.nameandprops.agethroughout the function. - Use Fragments for Multiple Root Elements: If you need to return multiple sibling elements without adding a wrapping
<div>, use a React Fragment:<>...</>. This keeps your DOM tree cleaner.
Anti-Patterns to Avoid:
- Don't define a component inside another component: This can lead to performance issues and bugs. Always define components at the top level of your module.
- Don't forget the
returnstatement: A component must return something to render, even if it's justnull. - Don't use array indexes as keys: When rendering lists with
map(), use a stable unique identifier (like an ID) as the key, never the array index. Index keys cause subtle bugs when lists are reordered.
Key Takeaways
- Three-Part Structure: Every functional component has an import, a function definition, and an export.
- The Return Statement is JSX: Components render by returning JSX, which Babel compiles to
React.createElement()calls. - Props are the Input: Components receive data through the
propsobject and render conditionally based on those props. - Composition is Powerful: Build complex UIs by nesting smaller, reusable components together.
- Naming Matters: Component names must start with a capital letter; filenames should match component names.
Frequently Asked Questions
What is the difference between a component and an HTML element?
A component is a JavaScript function that returns JSX describing a piece of UI. An HTML element is a built-in browser tag like <div> or <p>. React distinguishes between them by checking the first letter: capital letter = component (<UserProfile />), lowercase = HTML element (<div>).
Do I need to import React to use JSX?
In modern React projects (version 17+), you no longer need to explicitly import React to use JSX because Babel automatically includes the necessary imports. However, importing React is still good practice and required if you use React utilities like React.memo().
What are props, and how do they work?
Props are arguments passed to a component function. They're how parent components communicate data to child components. Props are read-only; you cannot modify them inside a component. If you need to change data, use the useState hook to manage internal component state.
Can a component return multiple elements?
No, a component's return statement must return a single root element. You can either wrap multiple elements in a <div> or use a React Fragment (<>...</>) to group them without adding extra DOM nodes.
What is the difference between JSX and HTML?
JSX is JavaScript code that looks like HTML. It's transformed into React.createElement() function calls at build time. Key differences: JSX attributes use camelCase (className, not class), you can embed JavaScript expressions with {}, and all tags must be self-closing (e.g., <input /> not <input>).