React Component Basic
Understanding React Components
In any React application, the building blocks are components. Components are independent, reusable pieces of JavaScript code that return HTML (or more accurately, JSX — JavaScript XML).
They help us split the UI into smaller, manageable parts. In React, there are two main types of components:
- Functional Components
- Class Components
Basic Example with Class Components
In our previous example, we rendered a Main component into the #root div element. That Main component was a class component.
Let’s walk through an example where we render multiple class components into different parts of the page.
<!DOCTYPE html>
<html>
<head>
<!-- React and ReactDOM via CDN -->
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<!-- Babel compiler for JSX support -->
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
<!-- External JSX file -->
<script src="/scripts/index.jsx" type="text/babel"></script>
</head>
<body>
<!-- You can name the divs anything, but "root" is common -->
<div id="root"></div>
<div id="second"></div>
</body>
</html>
In index.jsx, we can declare two class components and render them separately:
// index.jsx
class Main extends React.Component {
render() {
return <h1>Hello World, this is a React app</h1>;
}
}
class Second extends React.Component {
render() {
return <h1>Hello, I am the second component</h1>;
}
}
ReactDOM.render(<Main />, document.querySelector("#root"));
ReactDOM.render(<Second />, document.querySelector("#second"));
You can also reuse the same component in multiple places:
class Main extends React.Component {
render() {
return <h1>Hello World, this is a React app</h1>;
}
}
ReactDOM.render(<Main />, document.querySelector("#root"));
ReactDOM.render(<Main />, document.querySelector("#second"));
This is similar to manually writing document.createElement() and appendChild() in vanilla JavaScript — but with React, the code is cleaner and more powerful.
Functional Component Example
Here’s how we can write the same Main component using a functional component:
function Main() {
return <h1>Hello, this is a React app example</h1>;
}
ReactDOM.render(<Main />, document.querySelector("#root"));
Note: React components must return a single parent element. If you want to return multiple elements, wrap them in a
or a React Fragment (<>…</>).
// ❌ Invalid: multiple top-level elements
function Test() {
return (
<h1>Hello World</h1>
<p>Something</p>
);
}
// ✅ Valid: wrapped in a <div>
function Test2() {
return (
<div>
<h1>Hello World</h1>
<p>Something</p>
</div>
);
}
Nesting Components
Components can be nested inside each other. Here’s an example where we pass content to a child component using props.children.
function Hello(props) {
return <h1>Hello from Hello, {props.children}</h1>;
}
class Main extends React.Component {
render() {
return (
<div>
This is from Main,
<Hello>This is an example of a nested component.</Hello>
</div>
);
}
}
ReactDOM.render(<Main />, document.querySelector("#root"));
Notice how we use props.children to access the content passed between the <Hello>...</Hello> tags. We’ll talk more about props in the next section.
Reusable Components
One of the main advantages of React is reusability. Instead of repeating code, we can create a customizable component and reuse it throughout the app.
For example, we can make a Button component that accepts props for text and event handlers:
function Hello(props) {
return <h1>Hello, {props.children}</h1>;
}
class Button extends React.Component {
constructor(props) {
super(props);
this.onClickHandler = this.onClickHandler.bind(this);
this.onMouseOverHandler = this.onMouseOverHandler.bind(this);
}
onClickHandler() {
if (typeof this.props.clickHandler === "function") {
this.props.clickHandler();
}
console.log("Do something");
}
onMouseOverHandler() {
if (typeof this.props.mouseOverHandler === "function") {
this.props.mouseOverHandler();
}
}
render() {
return (
<buttononClick={this.onClickHandler}
onMouseOver={this.onMouseOverHandler}
>
{this.props.text}
</button>
);
}
}
class Main extends React.Component {
showAlert() {
alert("Button clicked!");
}
render() {
return (
<div>
This is from Main,
<Hello>This is an example of a nested component.</Hello>
{/* Reusing the same Button component with different props */}
<Button text="Button One" clickHandler={this.showAlert} />
<Buttontext="Button Two"
mouseOverHandler={() => {
alert("Mouse over me!");
}}
/>
</div>
);
}
}
ReactDOM.render(<Main />, document.querySelector("#root"));
In this example:
- The
Buttoncomponent acceptstext,clickHandler, andmouseOverHandleras props. - We reuse it with different behaviors by passing different functions.
- This makes our code modular, clean, and maintainable.
Final Thoughts
React components — whether functional or class-based — are the foundation of any React app. Understanding how to create, nest, and reuse components is essential for building modern front-end applications. In upcoming sections, we’ll dive deeper into props, state, and lifecycle methods, and explore how to manage more complex UI.