In React, a Component is a fundamental building block. Think of your entire user interface (UI) as being made up of independent, reusable pieces. Each of these pieces is a component.
Components allow you to:
- Split the UI: Break down complex UIs into smaller, manageable parts.
- Reuse Code: Create a component once and use it multiple times throughout your application, or even in different projects.
- Manage Logic: Each component can have its own logic for how it behaves and renders.
In modern React, we primarily use Functional Components.
Key Concepts of Functional Components:
- Simply JavaScript Functions: A functional component is literally a regular JavaScript function.
- Returns JSX: This function returns JSX (JavaScript XML), which is a syntax extension that looks like HTML within your JavaScript code. React uses JSX to describe what the UI should look like.
- Props as Arguments: Functional components receive data from their parent components through a single argument called
props
(short for “properties”). - Hooks for Features: To add features like local state and side effects (like data fetching) to functional components, we use special functions called “Hooks” (e.g.,
useState
,useEffect
).
Practical Code Examples:
1. Basic Functional Component
This is the simplest form of a React component. It just renders some static content.
// src/components/Greeting.jsx
import React from 'react'; // React is implicitly used by JSX, so it's good practice to import it.
// Define a functional component using a standard function declaration
function Greeting() {
return (
// JSX is returned from the component
<div>
<h1>Hello from my first React Component!</h1>
<p>This is a simple, reusable UI piece.</p>
</div>
);
}
// Export the component so it can be used in other files
export default Greeting;
// How you would use this component in another file (e.g., App.jsx):
// (Remember to create a new file like App.jsx in your src/ folder if you don't have one)
// src/App.jsx
import React from 'react';
import Greeting from './components/Greeting'; // Import your component
function App() {
return (
<div className="App">
<Greeting /> {/* Render your component like an HTML tag */}
<p>This text is from the App component.</p>
</div>
);
}
export default App;
2. Component with [[Props]]
Props allow you to pass data from a parent component to a child component. They make components dynamic and reusable. Props are read-only in the child component.
// src/components/WelcomeMessage.jsx
import React from 'react';
// Define a functional component. We use object destructuring to directly access 'name' and 'age' from the 'props' object.
const WelcomeMessage = ({ name, age }) => {
return (
<div>
<h2>Welcome, {name}!</h2>
<p>You are {age} years old.</p>
{/* You can use JavaScript expressions in JSX using curly braces {} */}
{age > 30 && <p>You have some life experience!</p>} {/* Conditional rendering */}
</div>
);
};
export default WelcomeMessage;
/*
// How you would use this component in another file (e.g., App.jsx):
// src/App.jsx
import React from 'react';
import WelcomeMessage from './components/WelcomeMessage';
function App() {
return (
<div className="App">
{/* Pass data to the WelcomeMessage component using attributes. These become 'props'. */}
<WelcomeMessage name="Alice" age={28} />
<WelcomeMessage name="Bob" age={40} /> {/* Reusing with different data */}
</div>
);
}
export default App;
*/
3. Component with [[useState Hook]]
(Local State Management)
The useState
Hook lets functional components manage their own internal data (called “state”) that can change over time. When state changes, React re-renders the component to reflect the new state.
// src/components/Counter.jsx
import React, { useState } from 'react'; // Import the useState Hook
const Counter = () => {
// `useState` returns an array with two elements:
// 1. `count`: The current state value (initialized to 0).
// 2. `setCount`: A function to update the `count` state.
const [count, setCount] = useState(0);
// Function to increment the counter
const increment = () => {
// When updating state based on its previous value, it's best to use
// a function inside `setCount` to ensure you're always working with the latest state.
setCount(prevCount => prevCount + 1);
};
// Function to decrement the counter, preventing it from going below 0
const decrement = () => {
setCount(prevCount => (prevCount > 0 ? prevCount - 1 : 0));
};
return (
<div>
<h3>Current Count: {count}</h3>
<button onClick={increment}>Increment</button> {/* Attach event handlers */}
<button onClick={decrement}>Decrement</button>
{count === 0 && <p>Count is at its minimum!</p>} {/* UI reacts to state changes */}
</div>
);
};
export default Counter;
/*
// How you would use this component in another file (e.g., App.jsx):
// src/App.jsx
import React from 'react';
import Counter from './components/Counter';
function App() {
return (
<div className="App">
<Counter /> {/* Each Counter component will have its own independent count */}
<Counter />
</div>
);
}
export default App;
*/
4. Component with [[useEffect Hook]]
(Side Effects)
The useEffect
Hook lets you perform “side effects” in functional components. Side effects are operations that interact with the outside world, like fetching data from an API, setting up event listeners, or directly manipulating the DOM.
// src/components/TitleUpdater.jsx
import React, { useState, useEffect } from 'react'; // Import useState and useEffect Hooks
const TitleUpdater = () => {
const [clickCount, setClickCount] = useState(0);
// `useEffect` Hook: This function will run after every render of the component.
// We want to update the browser tab title based on `clickCount`.
useEffect(() => {
// This code runs AFTER the component has rendered to the screen.
document.title = `You clicked ${clickCount} times`;
// The optional 'return' function is a cleanup function.
// It runs before the effect re-runs (if dependencies change) or when the component unmounts.
return () => {
// console.log("Cleaning up previous effect (e.g., removing event listener)");
};
}, [clickCount]); // [[Dependency Array]]: This array tells React WHEN to re-run the effect.
// If `clickCount` changes, the effect will re-run.
// If it's an empty array `[]`, the effect runs only once after the initial render (on "mount").
// If omitted, the effect runs after every render.
return (
<div>
<h3>Browser Tab Title will update!</h3>
<p>Click the button to see the title change.</p>
<button onClick={() => setClickCount(clickCount + 1)}>
Click me ({clickCount} times)
</button>
</div>
);
};
export default TitleUpdater;
/*
// How you would use this component in another file (e.g., App.jsx):
// src/App.jsx
import React from 'react';
import TitleUpdater from './components/TitleUpdater';
function App() {
return (
<div className="App">
<TitleUpdater />
</div>
);
}
export default App;
*/