Module 1 • 45 min read

React Fundamentals: Components, Props & State

Master the core building blocks of React and learn how to create dynamic, interactive user interfaces.

What You'll Learn

  • Understanding React components and JSX syntax
  • Working with props to pass data between components
  • Managing component state with useState hook
  • Building a real-world interactive component

1. Understanding React Components

React components are the building blocks of any React application. Think of them as reusable pieces of UI that can be composed together to create complex interfaces. There are two types of components: functional and class components. We'll focus on functional components as they're the modern standard.

Your First Component

// Welcome.tsx
function Welcome() {
  return (
    <div>
      <h1>Hello, React!</h1>
      <p>Welcome to your first component.</p>
    </div>
  );
}

export default Welcome;

This simple component returns JSX, which looks like HTML but is actually JavaScript. JSX gets compiled to React.createElement() calls behind the scenes.

2. Working with Props

Props (short for properties) allow you to pass data from parent components to child components. They make components reusable and dynamic. Props are read-only and should never be modified by the child component.

Using Props

// UserCard.tsx
interface UserCardProps {
  name: string;
  role: string;
  email: string;
}

function UserCard({ name, role, email }: UserCardProps) {
  return (
    <div className="card">
      <h2>{name}</h2>
      <p className="role">{role}</p>
      <p className="email">{email}</p>
    </div>
  );
}

// Using the component
<UserCard 
  name="Sarah Johnson" 
  role="Senior Developer" 
  email="sarah@example.com" 
/>

3. Managing State with useState

State allows components to remember information and re-render when that information changes. The useState hook is the most common way to add state to functional components.

Counter Component with State

import { useState } from 'react';

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

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

4. Practical Example: Todo List

Let's combine everything we've learned to build a simple todo list application. This example demonstrates components, props, and state working together.

Complete Todo App

import { useState } from 'react';

interface Todo {
  id: number;
  text: string;
  completed: boolean;
}

function TodoApp() {
  const [todos, setTodos] = useState<Todo[]>([]);
  const [input, setInput] = useState('');

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

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

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

  return (
    <div className="todo-app">
      <h1>My Todo List</h1>
      
      <div className="input-section">
        <input
          value={input}
          onChange={(e) => setInput(e.target.value)}
          onKeyPress={(e) => e.key === 'Enter' && addTodo()}
          placeholder="Add a new task..."
        />
        <button onClick={addTodo}>Add</button>
      </div>

      <ul className="todo-list">
        {todos.map(todo => (
          <li key={todo.id}>
            <input
              type="checkbox"
              checked={todo.completed}
              onChange={() => toggleTodo(todo.id)}
            />
            <span style={{
              textDecoration: todo.completed ? 'line-through' : 'none'
            }}>
              {todo.text}
            </span>
            <button onClick={() => deleteTodo(todo.id)}>
              Delete
            </button>
          </li>
        ))}
      </ul>
    </div>
  );
}

Key Takeaways

  • Components are reusable UI building blocks that return JSX
  • Props pass data from parent to child components (one-way data flow)
  • State allows components to remember and react to changes
  • useState returns current state and a function to update it
  • Always use TypeScript interfaces to define prop types for better type safety

Practice Exercises

Challenge Yourself

  1. 1. Profile Card: Create a ProfileCard component that accepts name, bio, and avatar URL as props. Style it nicely with Tailwind CSS.
  2. 2. Like Button: Build a button that tracks the number of likes. Add a heart icon that changes color when clicked.
  3. 3. Form Validation: Create a signup form with email and password fields. Use state to track input values and show validation errors.
  4. 4. Shopping Cart: Build a simple shopping cart where users can add items, change quantities, and see the total price.

Continue Learning

Next: React Hooks Deep Dive

Learn useEffect, useContext, and custom hooks to build more powerful components.

Practice on HalfGrade

Try interactive coding challenges to reinforce what you've learned.