Table of Contents
- What is React?
- Prerequisites
- Setting Up Your First React Project
- Understanding the React Project Structure
- Your First React Component
- Props: Passing Data Between Components
- State: Managing Dynamic Data
- Handling Events in React
- Conditional Rendering
- Lists and Keys
- Styling React Components
- Running and Building Your React App
- Next Steps: What to Learn After the Basics
- References
What is React?
React (officially “React.js” or “ReactJS”) is an open-source JavaScript library for building user interfaces, with a focus on component-based development and declarative programming. Let’s break down these terms:
Component-Based Architecture
React apps are built using components—reusable, self-contained pieces of code that render a part of the UI. Think of components as building blocks: a button, a navigation bar, a user profile card, or even an entire page can be a component. Components can be nested, reused, and combined to create complex UIs, making your code modular and easier to maintain.
Declarative Programming
Unlike “imperative” approaches (where you tell the computer how to do something step-by-step), React is declarative: you describe what you want the UI to look like, and React handles the “how” (i.e., updating the DOM when data changes). For example, instead of manually manipulating the DOM with document.getElementById or innerHTML, you define the desired state of your UI, and React automatically syncs it with the actual DOM.
Virtual DOM
One of React’s most powerful features is the Virtual DOM—a lightweight in-memory copy of the actual DOM. When your app’s data changes, React first updates the Virtual DOM, compares it with the previous version (a process called “reconciliation”), and then only updates the parts of the actual DOM that changed (a “diffing” algorithm). This makes React apps incredibly fast, even with frequent updates.
In short: React simplifies building dynamic UIs by letting you write reusable components, describe your UI declaratively, and leverage the Virtual DOM for performance.
Prerequisites
Before diving into React, you’ll need a basic understanding of a few core technologies. Don’t worry—you don’t need to be an expert, but familiarity with these will make your React journey much smoother:
1. HTML/CSS
React uses a syntax called JSX (more on this later) that resembles HTML, so knowing how to structure elements (e.g., <div>, <p>, <button>) and style them with CSS is essential.
2. JavaScript (ES6+)
React is built on JavaScript, and modern React development relies heavily on ES6+ features. Make sure you’re comfortable with:
- Variables (
let,const) - Arrow functions (
() => {}) - Template literals (
`Hello ${name}`) - Destructuring (
const { name } = user) - Spread/rest operators (
...) - Modules (
import/export)
3. Node.js and npm
To set up and run React projects, you’ll need Node.js (a JavaScript runtime) and npm (Node Package Manager, which comes with Node.js). They let you install React tools and dependencies.
Check if you have Node.js/npm installed: Open your terminal and run:
node -v # Should return a version (e.g., v18.17.0)
npm -v # Should return a version (e.g., 9.6.7)
If not, download Node.js from nodejs.org (LTS version recommended for beginners).
Setting Up Your First React Project
The easiest way to start a React project is with Create React App (CRA)—a tool built by the React team that sets up a modern React environment with zero configuration. It handles bundling, transpilation, and dev server setup, so you can focus on writing code.
Step 1: Create a New React App
Open your terminal and run the following command. Replace my-first-react-app with your project name (use lowercase and hyphens for spaces):
npx create-react-app my-first-react-app
npxis a tool that lets you run npm packages without installing them globally (no need tonpm install -g create-react-app).- This command will:
- Create a new folder named
my-first-react-app. - Install all dependencies (React, ReactDOM, Babel, Webpack, etc.).
- Set up a basic project structure.
- Create a new folder named
Step 2: Navigate to the Project Folder
Once the setup finishes, move into your new project directory:
cd my-first-react-app
Step 3: Start the Development Server
Run the following command to launch a local development server:
npm start
After a few seconds, your app will open automatically in your default browser at http://localhost:3000. You’ll see a React logo spinning—a sign that your app is up and running!
Pro Tip: The development server supports “hot reloading”: any changes you make to your code will automatically update in the browser without needing to refresh.
Understanding the Project Structure
Let’s take a tour of the files and folders created by Create React App. Open the my-first-react-app folder in your code editor (e.g., VS Code) to explore:
Key Folders/Files
| File/Folder | Purpose |
|---|---|
node_modules/ | Contains all installed dependencies (React, Babel, etc.). Don’t edit this! |
public/ | Static assets (HTML, images, favicon). index.html is the app’s entry point. |
src/ | Your React code lives here! Contains components, styles, and logic. |
package.json | Metadata about your project (name, scripts, dependencies). |
Critical Files in src/
-
index.js: The “root” of your React app. It renders your top-level component (App.js) into the DOM.import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App from './App'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <App /> </React.StrictMode> );Here,
ReactDOM.createRootattaches React to the<div id="root">element inpublic/index.html. -
App.js: The main component of your app. By default, it renders the React logo and some text.import logo from './logo.svg'; import './App.css'; function App() { return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p>Hello React!</p> </header> </div> ); } export default App; -
index.html(inpublic/): The HTML template for your app. The<div id="root">is where React injects your UI.
Your First React Component
Now that your project is set up, let’s create a simple React component. Components are the building blocks of React apps, and there are two main types: functional components (using functions) and class components (using ES6 classes). Today, functional components are preferred (especially with React hooks), so we’ll focus on those.
What is a Functional Component?
A functional component is a JavaScript function that returns JSX (a syntax extension for JavaScript that looks like HTML). JSX lets you write HTML-like code directly in your JavaScript, making it easy to describe your UI.
Example: A Simple Greeting Component
Let’s create a component that displays a greeting message.
- In the
src/folder, create a new file namedGreeting.js. - Add the following code:
// Greeting.js
function Greeting() {
return <h1>Hello, React Beginners!</h1>;
}
export default Greeting;
Using the Component in App.js
Now, let’s use the Greeting component in App.js. Import it at the top, then include it in the JSX:
// App.js
import './App.css';
import Greeting from './Greeting'; // Import the Greeting component
function App() {
return (
<div className="App">
<Greeting /> {/* Use the component like an HTML tag */}
</div>
);
}
export default App;
Save the files, and check http://localhost:3000—you’ll see “Hello, React Beginners!” displayed on the page. Congratulations—you just created and used your first React component!
JSX Rules to Remember
JSX looks like HTML, but there are a few key differences:
-
Class vs.
className: In HTML, you useclassto add CSS classes. In JSX, useclassName(becauseclassis a reserved word in JavaScript):<div className="container">Hello</div> {/* Correct */} <div class="container">Hello</div> {/* Incorrect! */} -
Self-Closing Tags: All tags must be closed, even self-closing ones like
<img>or<input>:<img src={logo} alt="logo" /> {/* Correct */} <img src={logo} alt="logo"> {/* Incorrect! */} -
Embed JavaScript with
{}: To use JavaScript expressions (variables, functions, etc.) in JSX, wrap them in curly braces{}:const name = "Alice"; return <h1>Hello, {name}!</h1>; {/* Renders: "Hello, Alice!" */}
Props: Passing Data Between Components
Components often need to share data. For example, a UserProfile component might need a name or avatar to display. Props (short for “properties”) let you pass data from a parent component to a child component.
How Props Work
- Props are passed like HTML attributes:
<Component propName="value" />. - Child components receive props as a function parameter and can use them in their JSX.
- Props are read-only: Child components cannot modify props (they’re “immutable”).
Example: A Reusable UserCard Component
Let’s create a UserCard component that accepts name, role, and avatar as props.
- Create
src/UserCard.js:
// UserCard.js
function UserCard(props) {
return (
<div className="user-card" style={{ border: "1px solid #ddd", padding: "16px", maxWidth: "300px" }}>
<h2>{props.name}</h2>
<p>Role: {props.role}</p>
<img src={props.avatar} alt={props.name} style={{ width: "100px", borderRadius: "50%" }} />
</div>
);
}
export default UserCard;
- Use
UserCardinApp.jsand pass props:
// App.js
import './App.css';
import UserCard from './UserCard';
function App() {
return (
<div className="App">
<h1>Team Members</h1>
{/* Pass props to UserCard */}
<UserCard
name="Alice Smith"
role="Frontend Developer"
avatar="https://i.pravatar.cc/150?img=1"
/>
<UserCard
name="Bob Johnson"
role="Backend Developer"
avatar="https://i.pravatar.cc/150?img=2"
/>
</div>
);
}
export default App;
Result: You’ll see two user cards with different names, roles, and avatars. Props make components reusable—we used UserCard twice with different data!
Destructuring Props (Cleaner Syntax)
To avoid repeating props. everywhere, you can destructure the props object in the function parameters:
// UserCard.js (with destructuring)
function UserCard({ name, role, avatar }) { // Destructure props here
return (
<div className="user-card" style={{ border: "1px solid #ddd", padding: "16px", maxWidth: "300px" }}>
<h2>{name}</h2> {/* No need for props.name! */}
<p>Role: {role}</p>
<img src={avatar} alt={name} style={{ width: "100px", borderRadius: "50%" }} />
</div>
);
}
State: Managing Dynamic Data
Props are great for passing data into a component, but what if a component needs to manage its own dynamic data? For example:
- A counter that increments when a button is clicked.
- A form input that updates as the user types.
- A toggle switch that switches between “on” and “off”.
This is where state comes in. State is a built-in React feature that lets components store and manage mutable data. When state changes, the component re-renders to reflect the new data.
Using the useState Hook
To use state in functional components, we use React hooks—special functions that let you “hook into” React features. The most basic hook is useState.
Step 1: Import useState
First, import useState from React:
import { useState } from 'react';
Step 2: Initialize State
Call useState inside your component to declare a state variable. useState takes an initial value and returns an array with two elements:
- The current state value.
- A function to update the state (conventionally named
set[StateName]).
Example: A Counter Component
Let’s build a counter that increments/decrements when buttons are clicked.
- Create
src/Counter.js:
// Counter.js
import { useState } from 'react';
function Counter() {
// Initialize state: count starts at 0
const [count, setCount] = useState(0);
// Define functions to update state
const increment = () => setCount(count + 1);
const decrement = () => setCount(count - 1);
return (
<div className="counter" style={{ textAlign: "center", margin: "20px" }}>
<h2>Count: {count}</h2>
<button onClick={decrement} style={{ margin: "0 8px", padding: "8px 16px" }}>-</button>
<button onClick={increment} style={{ margin: "0 8px", padding: "8px 16px" }}>+</button>
</div>
);
}
export default Counter;
- Use
CounterinApp.js:
// App.js
import './App.css';
import Counter from './Counter';
function App() {
return (
<div className="App">
<h1>My First Counter</h1>
<Counter />
</div>
);
}
How it works:
const [count, setCount] = useState(0)initializescountto0.incrementanddecrementare functions that callsetCountto updatecount.- When
setCountis called, React re-renders theCountercomponent with the newcountvalue.
Important: Never modify state directly! Always use the setter function:
// ❌ Bad: Directly modifying state (React won’t re-render)
count = count + 1;
// ✅ Good: Using the setter function
setCount(count + 1);
Handling Events in React
Like HTML, React lets you handle user events (clicks, key presses, form submissions, etc.). The syntax is similar to HTML, but with a few differences:
- React events are named in camelCase (e.g.,
onClickinstead ofonclick). - Event handlers are passed as functions (not strings).
Common Events
onClick: Triggered when an element is clicked.onChange: Triggered when an input’s value changes (e.g., typing in a text field).onSubmit: Triggered when a form is submitted.
Example: Form Input with onChange
Let’s create a component with a text input that updates state as the user types.
// NameInput.js
import { useState } from 'react';
function NameInput() {
const [name, setName] = useState("");
// Handle input changes
const handleChange = (e) => {
setName(e.target.value); // e.target.value is the input’s current value
};
return (
<div>
<input
type="text"
placeholder="Enter your name"
value={name} // Set input value to state
onChange={handleChange} // Update state on change
style={{ padding: "8px", margin: "10px" }}
/>
<p>Hello, {name || "stranger"}!</p>
</div>
);
}
export default NameInput;
Here, e.target.value gives us the current text in the input, and setName updates the name state. The input’s value is tied to name, making it a controlled component (React manages its value).
Conditional Rendering
React lets you render different UI elements based on conditions (e.g., user roles, loading states, or form validation). There are several ways to do this:
1. Ternary Operator
Use condition ? expressionIfTrue : expressionIfFalse for inline conditions.
function Greeting({ isLoggedIn }) {
return (
<div>
{isLoggedIn ? <h1>Welcome back!</h1> : <h1>Please log in.</h1>}
</div>
);
}
2. Logical && Operator
Render a component only if a condition is true using condition && expression.
function Notification({ hasUnreadMessages }) {
return (
<div>
<h1>Your Inbox</h1>
{hasUnreadMessages && <p>You have unread messages!</p>}
</div>
);
}
3. If/Else Statements
For more complex logic, use regular if/else outside the JSX return statement.
function UserDashboard({ user }) {
if (!user) {
return <p>Loading...</p>;
}
if (user.role === "admin") {
return <AdminDashboard user={user} />;
} else {
return <RegularUserDashboard user={user} />;
}
}
Lists and Keys
React makes it easy to render lists of items (e.g., todo lists, product grids) using the map method. When rendering lists, you must include a key prop for each item to help React identify which items have changed, been added, or removed.
Why Keys Matter
Keys are unique identifiers for list items. They help React optimize re-renders by avoiding unnecessary updates to the DOM. Always use a stable, unique value for keys (e.g., an id from a database). Avoid using array indexes as keys (they can cause bugs if the list is reordered).
Example: Rendering a List of Todos
Let’s render a list of todo items using map and keys.
// TodoList.js
function TodoList() {
const todos = [
{ id: 1, text: "Learn React" },
{ id: 2, text: "Build a project" },
{ id: 3, text: "Deploy to the web" }
];
return (
<ul>
{todos.map((todo) => (
<li key={todo.id} style={{ padding: "8px" }}>
{todo.text}
</li>
))}
</ul>
);
}
export default TodoList;
Here, todos.map((todo) => ...) iterates over the todos array and returns a <li> for each item. The key={todo.id} ensures React can track each todo efficiently.
Styling in React
There are many ways to style React components. Here are the most common approaches:
1. Inline Styles
Define styles as JavaScript objects and pass them to the style prop. Use camelCase for CSS properties (e.g., backgroundColor instead of background-color).
<div style={{ color: "blue", fontSize: "20px", padding: "16px" }}>
Styled with inline styles!
</div>
2. CSS Files
Import external CSS files into your components. Styles are global by default, so use unique class names to avoid conflicts.
/* Button.css */
.primary-button {
background: #007bff;
color: white;
padding: 8px 16px;
border: none;
border-radius: 4px;
}
// Button.js
import './Button.css';
function Button() {
return <button className="primary-button">Click Me</button>;
}
3. CSS Modules
To scope styles to a single component (avoid global conflicts), use CSS Modules. Rename your CSS file to [FileName].module.css, then import it as an object.
/* Button.module.css */
.primary {
background: #007bff;
color: white;
padding: 8px 16px;
}
// Button.js
import styles from './Button.module.css';
function Button() {
return <button className={styles.primary}>Click Me</button>;
}
4. Styled Components (Bonus)
For more advanced styling, libraries like styled-components let you write CSS directly in your JavaScript, creating reusable styled elements.
import styled from 'styled-components';
// Create a styled button
const StyledButton = styled.button`
background: #007bff;
color: white;
padding: 8px 16px;
border: none;
border-radius: 4px;
&:hover {
background: #0056b3;
}
`;
function Button() {
return <StyledButton>Click Me</StyledButton>;
}
Running and Building Your App
Now that you’ve built your React app, you’ll want to run it locally during development and build it for production.
Running the Development Server
We already did this earlier, but as a reminder:
npm start
This starts a local server at http://localhost:3000. The app will automatically reload when you make changes to your code.
Building for Production
When you’re ready to deploy your app, run:
npm run build
This creates an optimized production build in the build/ folder. The build is minified, and filenames include hashes for caching. You can then deploy the build/ folder to a hosting service like Netlify, Vercel, or GitHub Pages.
Next Steps: What to Learn After the Basics
Congratulations! You now have a solid foundation in React. To take your skills further, here are some key topics to explore next:
1. React Router
Learn to add navigation to your app with react-router-dom (e.g., multi-page apps, dynamic routes).
2. State Management
For larger apps, use tools like:
- Context API: Built into React for sharing state across components.
- Redux: A popular library for managing global state (great for complex apps).
- Zustand/Jotai: Lighter alternatives to Redux.
3. React Hooks Deep Dive
Master advanced hooks like:
useEffect: Handle side effects (e.g., API calls, subscriptions).useContext: Access context values.useReducer: Manage complex state logic.
4. API Integration
Learn to fetch data from APIs using fetch or axios, and handle loading/error states.
5. Testing
Write tests for your components with tools like Jest and React Testing Library.
References
- React Official Documentation: react.dev (the best resource for learning React).
- Create React App: create-react-app.dev
- MDN JavaScript Guide: developer.mozilla.org/en-US/docs/Web/JavaScript/Guide (brush up on JS fundamentals).
- React Router: reactrouter.com
- CSS Modules: github.com/css-modules/css-modules
You’re now ready to start building your own React apps! Remember, practice is key—build small projects (a todo app, a weather dashboard, or a portfolio site) to reinforce what you’ve learned. Happy coding! 🚀