CodeMasteryLab
Tutorials / All Technologies / React Complete Guide for Beginners

React Complete Guide for Beginners

A complete tutorial covering all React fundamentals including JSX, components, props, state management, hooks like useState and useEffect, event handling, and conditional rendering.

beginneršŸ“– 45 min readšŸ‘ 68 views
šŸ’”

What You'll Learn

  • āœ“ Master React concepts
  • āœ“ Practical code examples
  • āœ“ Real-world applications
  • āœ“ Best practices & tips
šŸ’” Pro Tip:

Bookmark this page and practice the examples in your own editor!

React Complete Guide for Beginners

Welcome to the complete React tutorial! React is a powerful JavaScript library for building user interfaces, created and maintained by Facebook (Meta). This guide will take you from zero to hero in React development.

Table of Contents

  1. What is React?
  2. Getting Started
  3. Components and JSX
  4. Props: Passing Data
  5. State Management
  6. Hooks Deep Dive
  7. Event Handling
  8. Conditional Rendering
  9. Lists and Keys
  10. Real-World Example

What is React?

React is a JavaScript library for building user interfaces, particularly single-page applications where you need a fast, interactive user experience. React was created by Jordan Walke, a software engineer at Facebook, and was first deployed on Facebook's newsfeed in 2011.

Key Features of React

  • Component-Based: Build encapsulated components that manage their own state
  • Declarative: Design simple views for each state in your application
  • Learn Once, Write Anywhere: Use React for web, mobile (React Native), and even VR
  • Virtual DOM: Efficient rendering and updates
  • Unidirectional Data Flow: Makes debugging easier and code more predictable

Why Learn React?

  1. High Demand: React is one of the most in-demand skills in web development
  2. Strong Ecosystem: Massive community, extensive libraries, and tools
  3. Performance: Virtual DOM makes React applications fast
  4. Career Growth: Used by Facebook, Netflix, Airbnb, Instagram, and thousands more

Getting Started

Prerequisites

Before learning React, you should have a basic understanding of:

  • HTML & CSS
  • JavaScript (ES6+ features like arrow functions, destructuring, spread operator)
  • DOM manipulation basics

Setting Up Your Environment

Option 1: Create React App (Recommended for Beginners)

# Create a new React app
npx create-react-app my-react-app

# Navigate to the project
cd my-react-app

# Start the development server
npm start

Option 2: Online Playground

Use online editors like:

Project Structure

After creating a React app, you'll see this structure:

my-react-app/
ā”œā”€ā”€ node_modules/
ā”œā”€ā”€ public/
│   ā”œā”€ā”€ index.html
│   └── favicon.ico
ā”œā”€ā”€ src/
│   ā”œā”€ā”€ App.js
│   ā”œā”€ā”€ App.css
│   ā”œā”€ā”€ index.js
│   └── index.css
ā”œā”€ā”€ package.json
└── README.md

Components and JSX

What are Components?

Components are the building blocks of React applications. They are reusable pieces of UI that can have their own logic and styling.

Functional Components

Modern React uses functional components with hooks:

// Simple functional component
function Welcome() {
  return <h1>Hello, World!</h1>;
}

// Or using arrow function
const Welcome = () => {
  return <h1>Hello, World!</h1>;
};

export default Welcome;

JSX Syntax

JSX (JavaScript XML) allows you to write HTML-like code in JavaScript:

function Profile() {
  const user = {
    name: "Sarah Johnson",
    imageUrl: "https://i.imgur.com/yXOvdOSs.jpg",
    imageSize: 90
  };

  return (
    <div className="profile">
      <h1>{user.name}</h1>
      <img
        className="avatar"
        src={user.imageUrl}
        alt={'Photo of ' + user.name}
        style={{
          width: user.imageSize,
          height: user.imageSize,
          borderRadius: '50%'
        }}
      />
    </div>
  );
}

JSX Rules

  1. Single Parent Element: Must return one parent element
// āœ… Correct
function MyComponent() {
  return (
    <div>
      <h1>Title</h1>
      <p>Content</p>
    </div>
  );
}

// āŒ Wrong
function MyComponent() {
  return (
    <h1>Title</h1>
    <p>Content</p>
  );
}

// āœ… Use Fragment
function MyComponent() {
  return (
    <>
      <h1>Title</h1>
      <p>Content</p>
    </>
  );
}
  1. Close All Tags: Self-closing tags must have />
<img src="image.jpg" alt="Description" />
<br />
<input type="text" />
  1. className Instead of class: Use className for CSS classes
<div className="container">Content</div>
  1. Curly Braces for JavaScript: Use {} to embed JavaScript
const name = "React";
return <h1>Welcome to {name}</h1>;

Props: Passing Data

Props (properties) allow you to pass data from parent to child components.

Basic Props

// Child component receiving props
function Welcome(props) {
  return <h1>Hello, {props.name}!</h1>;
}

// Parent component passing props
function App() {
  return (
    <div>
      <Welcome name="Alice" />
      <Welcome name="Bob" />
      <Welcome name="Charlie" />
    </div>
  );
}

Destructuring Props

// Cleaner way using destructuring
function Welcome({ name, age, city }) {
  return (
    <div>
      <h1>Hello, {name}!</h1>
      <p>Age: {age}</p>
      <p>City: {city}</p>
    </div>
  );
}

function App() {
  return <Welcome name="Alice" age={25} city="New York" />;
}

Props with Objects

function UserCard({ user }) {
  return (
    <div className="user-card">
      <img src={user.avatar} alt={user.name} />
      <h2>{user.name}</h2>
      <p>{user.email}</p>
      <p>{user.role}</p>
    </div>
  );
}

function App() {
  const userData = {
    name: "Sarah Johnson",
    email: "sarah@example.com",
    role: "Developer",
    avatar: "https://i.imgur.com/avatar.jpg"
  };

  return <UserCard user={userData} />;
}

Props.children

Special prop that contains content between component tags:

function Card({ children, title }) {
  return (
    <div className="card">
      <h2>{title}</h2>
      <div className="card-content">
        {children}
      </div>
    </div>
  );
}

function App() {
  return (
    <Card title="Welcome">
      <p>This is the card content</p>
      <button>Click me</button>
    </Card>
  );
}

State Management

State allows components to create and manage their own data. When state changes, the component re-renders.

useState Hook

The most fundamental React hook for managing state:

import { useState } from 'react';

function Counter() {
  // Declare state variable
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Increment
      </button>
      <button onClick={() => setCount(count - 1)}>
        Decrement
      </button>
      <button onClick={() => setCount(0)}>
        Reset
      </button>
    </div>
  );
}

Multiple State Variables

function UserProfile() {
  const [name, setName] = useState('John');
  const [age, setAge] = useState(25);
  const [email, setEmail] = useState('john@example.com');

  return (
    <div>
      <h2>{name}</h2>
      <p>Age: {age}</p>
      <p>Email: {email}</p>
    </div>
  );
}

State with Objects

function UserForm() {
  const [user, setUser] = useState({
    firstName: '',
    lastName: '',
    email: ''
  });

  const handleChange = (e) => {
    setUser({
      ...user,
      [e.target.name]: e.target.value
    });
  };

  return (
    <form>
      <input
        name="firstName"
        value={user.firstName}
        onChange={handleChange}
        placeholder="First Name"
      />
      <input
        name="lastName"
        value={user.lastName}
        onChange={handleChange}
        placeholder="Last Name"
      />
      <input
        name="email"
        value={user.email}
        onChange={handleChange}
        placeholder="Email"
      />
    </form>
  );
}

State with Arrays

function TodoList() {
  const [todos, setTodos] = useState([]);
  const [input, setInput] = useState('');

  const addTodo = () => {
    if (input.trim()) {
      setTodos([...todos, { id: Date.now(), text: input }]);
      setInput('');
    }
  };

  const removeTodo = (id) => {
    setTodos(todos.filter(todo => todo.id !== id));
  };

  return (
    <div>
      <input
        value={input}
        onChange={(e) => setInput(e.target.value)}
        placeholder="Add a todo"
      />
      <button onClick={addTodo}>Add</button>
      <ul>
        {todos.map(todo => (
          <li key={todo.id}>
            {todo.text}
            <button onClick={() => removeTodo(todo.id)}>Delete</button>
          </li>
        ))}
      </ul>
    </div>
  );
}

Hooks Deep Dive

useEffect Hook

useEffect lets you perform side effects in function components (data fetching, subscriptions, manual DOM manipulation).

Basic useEffect

import { useState, useEffect } from 'react';

function DocumentTitle() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    // This runs after every render
    document.title = `You clicked ${count} times`;
  });

  return (
    <button onClick={() => setCount(count + 1)}>
      Click me
    </button>
  );
}

useEffect with Dependencies

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    // This runs only when userId changes
    setLoading(true);
    fetch(`https://api.example.com/users/${userId}`)
      .then(response => response.json())
      .then(data => {
        setUser(data);
        setLoading(false);
      });
  }, [userId]); // Dependency array

  if (loading) return <p>Loading...</p>;
  
  return (
    <div>
      <h2>{user.name}</h2>
      <p>{user.email}</p>
    </div>
  );
}

useEffect Cleanup

function Timer() {
  const [seconds, setSeconds] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setSeconds(s => s + 1);
    }, 1000);

    // Cleanup function
    return () => {
      clearInterval(interval);
    };
  }, []); // Empty array = run once on mount

  return <p>Seconds: {seconds}</p>;
}

useEffect Dependency Patterns

// Run once on mount
useEffect(() => {
  console.log('Component mounted');
}, []);

// Run on every render
useEffect(() => {
  console.log('Component rendered');
});

// Run when specific values change
useEffect(() => {
  console.log('Count changed');
}, [count]);

// Run when any of multiple values change
useEffect(() => {
  console.log('Count or name changed');
}, [count, name]);

Event Handling

React events are named using camelCase and pass functions as event handlers.

Button Click Events

function ButtonExample() {
  const handleClick = () => {
    alert('Button clicked!');
  };

  // Inline function
  const handleClickInline = () => {
    console.log('Inline click');
  };

  return (
    <div>
      <button onClick={handleClick}>Click Me</button>
      <button onClick={handleClickInline}>Inline Handler</button>
      <button onClick={() => alert('Direct inline')}>Direct</button>
    </div>
  );
}

Form Events

function LoginForm() {
  const [formData, setFormData] = useState({
    email: '',
    password: ''
  });

  const handleSubmit = (e) => {
    e.preventDefault(); // Prevent page reload
    console.log('Form submitted:', formData);
    // Send data to server
  };

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData(prev => ({
      ...prev,
      [name]: value
    }));
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="email"
        name="email"
        value={formData.email}
        onChange={handleChange}
        placeholder="Email"
      />
      <input
        type="password"
        name="password"
        value={formData.password}
        onChange={handleChange}
        placeholder="Password"
      />
      <button type="submit">Login</button>
    </form>
  );
}

Mouse Events

function MouseExample() {
  const [position, setPosition] = useState({ x: 0, y: 0 });

  return (
    <div
      onMouseMove={(e) => setPosition({ x: e.clientX, y: e.clientY })}
      onMouseEnter={() => console.log('Mouse entered')}
      onMouseLeave={() => console.log('Mouse left')}
      style={{ height: '200px', border: '1px solid black' }}
    >
      <p>X: {position.x}, Y: {position.y}</p>
    </div>
  );
}

Conditional Rendering

If-Else with Variables

function Greeting({ isLoggedIn }) {
  let content;
  
  if (isLoggedIn) {
    content = <h1>Welcome back!</h1>;
  } else {
    content = <h1>Please sign in</h1>;
  }
  
  return <div>{content}</div>;
}

Ternary Operator

function LoginStatus({ isLoggedIn }) {
  return (
    <div>
      {isLoggedIn ? (
        <button>Logout</button>
      ) : (
        <button>Login</button>
      )}
    </div>
  );
}

Logical && Operator

function Mailbox({ unreadMessages }) {
  return (
    <div>
      <h1>Hello!</h1>
      {unreadMessages.length > 0 && (
        <h2>You have {unreadMessages.length} unread messages.</h2>
      )}
    </div>
  );
}

Switch Statement Pattern

function StatusBadge({ status }) {
  const renderBadge = () => {
    switch (status) {
      case 'success':
        return <span className="badge-success">āœ“ Success</span>;
      case 'error':
        return <span className="badge-error">āœ— Error</span>;
      case 'warning':
        return <span className="badge-warning">⚠ Warning</span>;
      default:
        return <span className="badge-info">ℹ Info</span>;
    }
  };

  return <div>{renderBadge()}</div>;
}

Lists and Keys

Rendering Lists

function TodoList() {
  const todos = [
    { id: 1, text: 'Learn React', completed: false },
    { id: 2, text: 'Build a project', completed: false },
    { id: 3, text: 'Deploy to production', completed: true }
  ];

  return (
    <ul>
      {todos.map(todo => (
        <li key={todo.id}>
          {todo.text}
          {todo.completed && ' āœ“'}
        </li>
      ))}
    </ul>
  );
}

Keys Explained

Keys help React identify which items have changed, are added, or removed:

// āœ… Good - using unique ID
{items.map(item => <li key={item.id}>{item.name}</li>)}

// āš ļø OK - using index (only if list never changes)
{items.map((item, index) => <li key={index}>{item.name}</li>)}

// āŒ Bad - no key
{items.map(item => <li>{item.name}</li>)}

Complex List Example

function ProductList({ products }) {
  return (
    <div className="product-grid">
      {products.map(product => (
        <div key={product.id} className="product-card">
          <img src={product.image} alt={product.name} />
          <h3>{product.name}</h3>
          <p>${product.price}</p>
          <button>Add to Cart</button>
        </div>
      ))}
    </div>
  );
}

Real-World Example

Let's build a complete Todo App combining everything we've learned:

import { useState, useEffect } from 'react';

function TodoApp() {
  const [todos, setTodos] = useState([]);
  const [input, setInput] = useState('');
  const [filter, setFilter] = useState('all'); // all, active, completed

  // Load todos from localStorage
  useEffect(() => {
    const saved = localStorage.getItem('todos');
    if (saved) {
      setTodos(JSON.parse(saved));
    }
  }, []);

  // Save todos to localStorage
  useEffect(() => {
    localStorage.setItem('todos', JSON.stringify(todos));
  }, [todos]);

  const addTodo = (e) => {
    e.preventDefault();
    if (input.trim()) {
      setTodos([
        ...todos,
        {
          id: Date.now(),
          text: input,
          completed: false,
          createdAt: new Date().toISOString()
        }
      ]);
      setInput('');
    }
  };

  const toggleTodo = (id) => {
    setTodos(todos.map(todo =>
      todo.id === id ? { ...todo, completed: !todo.completed } : todo
    ));
  };

  const deleteTodo = (id) => {
    setTodos(todos.filter(todo => todo.id !== id));
  };

  const filteredTodos = todos.filter(todo => {
    if (filter === 'active') return !todo.completed;
    if (filter === 'completed') return todo.completed;
    return true;
  });

  return (
    <div className="todo-app">
      <h1>My Todo List</h1>
      
      {/* Add Todo Form */}
      <form onSubmit={addTodo}>
        <input
          type="text"
          value={input}
          onChange={(e) => setInput(e.target.value)}
          placeholder="What needs to be done?"
        />
        <button type="submit">Add</button>
      </form>

      {/* Filter Buttons */}
      <div className="filters">
        <button onClick={() => setFilter('all')}>All</button>
        <button onClick={() => setFilter('active')}>Active</button>
        <button onClick={() => setFilter('completed')}>Completed</button>
      </div>

      {/* Todo List */}
      <ul className="todo-list">
        {filteredTodos.map(todo => (
          <li key={todo.id} className={todo.completed ? 'completed' : ''}>
            <input
              type="checkbox"
              checked={todo.completed}
              onChange={() => toggleTodo(todo.id)}
            />
            <span>{todo.text}</span>
            <button onClick={() => deleteTodo(todo.id)}>Delete</button>
          </li>
        ))}
      </ul>

      {/* Stats */}
      <div className="stats">
        <p>{filteredTodos.length} items</p>
        <p>{todos.filter(t => !t.completed).length} active</p>
      </div>
    </div>
  );
}

export default TodoApp;

Next Steps

Congratulations! You've learned the fundamentals of React. Here's what to learn next:

Intermediate Topics

  • React Router: Navigation and routing
  • Context API: Advanced state management
  • Custom Hooks: Reusable logic
  • useReducer: Complex state logic
  • Performance Optimization: memo, useMemo, useCallback

Advanced Topics

  • TypeScript with React: Type-safe React apps
  • Testing: Jest and React Testing Library
  • State Management: Redux, Zustand, Recoil
  • Server-Side Rendering: Next.js
  • React Native: Mobile app development

Practice Projects

  1. Weather App with API
  2. E-commerce Product Page
  3. Social Media Dashboard
  4. Blog with Authentication
  5. Real-time Chat Application

Common Mistakes to Avoid

1. Mutating State Directly

// āŒ Wrong
state.count = state.count + 1;

// āœ… Correct
setState({ ...state, count: state.count + 1 });

2. Missing Keys in Lists

// āŒ Wrong
items.map(item => <li>{item}</li>)

// āœ… Correct
items.map((item, id) => <li key={id}>{item}</li>)

3. Forgetting to Prevent Default

// āŒ Wrong - page reloads
<form onSubmit={handleSubmit}>

// āœ… Correct
<form onSubmit={(e) => { e.preventDefault(); handleSubmit(); }}>

4. Comparing Objects in useEffect

// āŒ Wrong - runs every render
useEffect(() => {}, [objectProp]);

// āœ… Correct - compare specific properties
useEffect(() => {}, [objectProp.id, objectProp.name]);

Best Practices

  1. Keep Components Small: One component, one responsibility
  2. Use Functional Components: Prefer hooks over class components
  3. Meaningful Names: Use descriptive names for components and functions
  4. DRY Principle: Don't repeat yourself - create reusable components
  5. PropTypes or TypeScript: Add type checking
  6. Folder Structure: Organize components logically
  7. Comments: Document complex logic
  8. Error Boundaries: Handle errors gracefully

Resources


Conclusion

You now have a solid foundation in React! Remember:

  • Practice regularly: Build small projects
  • Read documentation: React docs are excellent
  • Join communities: Reddit, Discord, Stack Overflow
  • Stay updated: React evolves constantly
  • Contribute: Open source projects welcome beginners

Happy coding! šŸš€