Building Your Learning Module...
Getting things ready for you!
Find videos you like?
Save to resource drawer for future reference!
In React, arrays in state should be treated as immutable. When you need to change an array, you must create a new array and pass it to the state setter. This lets React detect that something changed and trigger a re-render.
React can't detect the change because the array reference is the same.
React sees the new array reference and triggers a re-render.
Complete CRUD operations on a todo array using immutable patterns
import React from 'react';
import { createRoot } from 'react-dom/client';
function TodoApp() {
const [todos, setTodos] = React.useState([
{ id: 1, text: 'Learn React arrays', completed: false },
{ id: 2, text: 'Build todo app', completed: true },
{ id: 3, text: 'Master state management', completed: false }
]);
const [input, setInput] = React.useState('');
// Add new todo (immutable)
const addTodo = () => {
if (input.trim()) {
const newTodo = {
id: Date.now(),
text: input.trim(),
completed: false
};
setTodos([...todos, newTodo]);
setInput('');
}
};
// Toggle todo completion (immutable)
const toggleTodo = (id) => {
setTodos(todos.map(todo =>
todo.id === id
? { ...todo, completed: !todo.completed }
: todo
));
};
// Delete todo (immutable)
const deleteTodo = (id) => {
setTodos(todos.filter(todo => todo.id !== id));
};
// Clear completed todos (immutable)
const clearCompleted = () => {
setTodos(todos.filter(todo => !todo.completed));
};
const completedCount = todos.filter(todo => todo.completed).length;
const remainingCount = todos.length - completedCount;
return (
<div className="todo-app">
<h1>๐ Array Operations Todo List</h1>
<p className="subtitle">
See how arrays are updated immutably in React
</p>
<div className="input-section">
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && addTodo()}
placeholder="What needs to be done?"
className="todo-input"
/>
<button onClick={addTodo} className="add-btn">
โ Add Todo
</button>
</div>
<div className="stats">
<span className="stat">Total: {todos.length}</span>
<span className="stat">Active: {remainingCount}</span>
<span className="stat">Done: {completedCount}</span>
</div>
<div className="todo-list">
{todos.map(todo => (
<div key={todo.id} className={'todo-item ' + (todo.completed ? 'completed' : '')}>
<input
type="checkbox"
checked={todo.completed}
onChange={() => toggleTodo(todo.id)}
className="checkbox"
/>
<span className="todo-text">{todo.text}</span>
<button
onClick={() => deleteTodo(todo.id)}
className="delete-btn"
>
๐๏ธ
</button>
</div>
))}
</div>
{completedCount > 0 && (
<button onClick={clearCompleted} className="clear-btn">
๐งน Clear {completedCount} completed
</button>
)}
<div className="code-explanation">
<h3>๐ Array Operations Used:</h3>
<ul>
<li><strong>Add:</strong> <code>[...todos, newTodo]</code></li>
<li><strong>Update:</strong> <code>todos.map(...)</code></li>
<li><strong>Delete:</strong> <code>todos.filter(...)</code></li>
<li><strong>Clear:</strong> <code>todos.filter(...)</code></li>
</ul>
</div>
</div>
);
}
const root = createRoot(document.getElementById('root'));
root.render(React.createElement(TodoApp));}Loading preview...
Add, remove, update quantities, and filter products in a shopping cart
import React from 'react';
import { createRoot } from 'react-dom/client';
function ShoppingCart() {
const [products] = React.useState([
{ id: 1, name: 'Laptop', price: 999, category: 'electronics' },
{ id: 2, name: 'Book', price: 29, category: 'books' },
{ id: 3, name: 'Headphones', price: 199, category: 'electronics' },
{ id: 4, name: 'Mouse', price: 49, category: 'electronics' },
{ id: 5, name: 'Notebook', price: 19, category: 'books' }
]);
const [cart, setCart] = React.useState([]);
const [filter, setFilter] = React.useState('all');
const [sortBy, setSortBy] = React.useState('name');
// Add product to cart (immutable)
const addToCart = (product) => {
const existingItem = cart.find(item => item.id === product.id);
if (existingItem) {
// Update quantity (immutable)
setCart(cart.map(item =>
item.id === product.id
? { ...item, quantity: item.quantity + 1 }
: item
));
} else {
// Add new item (immutable)
setCart([...cart, { ...product, quantity: 1 }]);
}
};
// Remove from cart (immutable)
const removeFromCart = (id) => {
setCart(cart.filter(item => item.id !== id));
};
// Update quantity (immutable)
const updateQuantity = (id, quantity) => {
if (quantity <= 0) {
removeFromCart(id);
} else {
setCart(cart.map(item =>
item.id === id ? { ...item, quantity } : item
));
}
};
// Clear cart (immutable)
const clearCart = () => {
setCart([]);
};
// Filter products (derived state)
const filteredProducts = products.filter(product => {
if (filter === 'all') return true;
return product.category === filter;
});
// Sort products (derived state)
const sortedProducts = [...filteredProducts].sort((a, b) => {
if (sortBy === 'name') {
return a.name.localeCompare(b.name);
} else if (sortBy === 'price') {
return a.price - b.price;
}
return 0;
});
// Calculate total (derived state)
const cartTotal = cart.reduce((total, item) => {
return total + (item.price * item.quantity);
}, 0);
return (
<div className="cart-app">
<h1>๐ Shopping Cart Array Operations</h1>
<p className="subtitle">
Practice advanced array operations: filtering, sorting, and updating
</p>
<div className="controls">
<div className="filter-group">
<label>Filter:</label>
<select value={filter} onChange={(e) => setFilter(e.target.value)}>
<option value="all">All Products</option>
<option value="electronics">Electronics</option>
<option value="books">Books</option>
</select>
</div>
<div className="sort-group">
<label>Sort:</label>
<select value={sortBy} onChange={(e) => setSortBy(e.target.value)}>
<option value="name">Name</option>
<option value="price">Price</option>
</select>
</div>
</div>
<div className="products-section">
<h2>Products</h2>
<div className="products-grid">
{sortedProducts.map(product => (
<div key={product.id} className="product-card">
<h3>{product.name}</h3>
<p className="category">{product.category}</p>
<p className="price">{'$' + product.price}</p>
<button
onClick={() => addToCart(product)}
className="add-to-cart-btn"
>
๐๏ธ Add to Cart
</button>
</div>
))}
</div>
</div>
<div className="cart-section">
<h2>Shopping Cart ({cart.length} items)</h2>
{cart.length === 0 ? (
<p className="empty-cart">Your cart is empty</p>
) : (
<>
<div className="cart-items">
{cart.map(item => (
<div key={item.id} className="cart-item">
<div className="item-info">
<h4>{item.name}</h4>
<p>{'$' + item.price + ' x ' + item.quantity}</p>
</div>
<div className="item-controls">
<button
onClick={() => updateQuantity(item.id, item.quantity - 1)}
className="quantity-btn"
>
-
</button>
<span className="quantity">{item.quantity}</span>
<button
onClick={() => updateQuantity(item.id, item.quantity + 1)}
className="quantity-btn"
>
+
</button>
<button
onClick={() => removeFromCart(item.id)}
className="remove-btn"
>
๐๏ธ
</button>
</div>
</div>
))}
</div>
<div className="cart-summary">
<div className="total">
<strong>{'Total: $' + cartTotal}</strong>
</div>
<button onClick={clearCart} className="clear-cart-btn">
๐งน Clear Cart
</button>
</div>
</>
)}
</div>
<div className="operations-summary">
<h3>๐ Array Operations Used:</h3>
<div className="operations-grid">
<div>
<strong>Add/Update:</strong>
<code>cart.map(...)</code>
</div>
<div>
<strong>Add New:</strong>
<code>[...cart, newItem]</code>
</div>
<div>
<strong>Remove:</strong>
<code>cart.filter(...)</code>
</div>
<div>
<strong>Filter:</strong>
<code>products.filter(...)</code>
</div>
<div>
<strong>Sort:</strong>
<code>[...products].sort(...)</code>
</div>
<div>
<strong>Reduce:</strong>
<code>cart.reduce(...)</code>
</div>
</div>
</div>
</div>
);
}
const root = createRoot(document.getElementById('root'));
root.render(React.createElement(ShoppingCart));Loading preview...
[...items, newItem]items.filter(item => item.id !== id)items.map(item => item.id === id ? {...item, ...updates} : item)[...items].sort((a, b) => a.value - b.value)Array state management is fundamental to React development. Master these immutable patterns to build predictable, performant applications that scale well.