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