// Functional Component
function Greeting({ name }) {
return <h1>Hello, {name}!</h1>;
}
// Arrow Function Component
const Greeting = ({ name }) => {
return <h1>Hello, {name}!</h1>;
};
// With default props
const Button = ({ text = 'Click me', onClick }) => {
return <button onClick={onClick}>{text}</button>;
};
// Children prop
const Card = ({ children, title }) => {
return (
<div className="card">
<h2>{title}</h2>
{children}
</div>
);
};
import { useState } from 'react';
function Counter() {
// Basic state
const [count, setCount] = useState(0);
// State with object
const [user, setUser] = useState({ name: '', age: 0 });
// Update state
const increment = () => setCount(count + 1);
// Functional update (for state based on previous)
const incrementSafe = () => setCount(prev => prev + 1);
// Update object state
const updateName = (name) => {
setUser(prev => ({ ...prev, name }));
};
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>+</button>
</div>
);
}
import { useEffect, useState } from 'react';
function DataFetcher({ userId }) {
const [data, setData] = useState(null);
// Run on every render
useEffect(() => {
console.log('Rendered');
});
// Run once on mount
useEffect(() => {
console.log('Mounted');
return () => console.log('Unmounted'); // Cleanup
}, []);
// Run when dependency changes
useEffect(() => {
fetchUser(userId).then(setData);
}, [userId]);
// Async effect
useEffect(() => {
const fetchData = async () => {
const result = await fetchUser(userId);
setData(result);
};
fetchData();
}, [userId]);
return <div>{data?.name}</div>;
}
import { createContext, useContext, useState } from 'react';
// Create context
const ThemeContext = createContext();
// Provider component
function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');
const toggleTheme = () => {
setTheme(prev => prev === 'light' ? 'dark' : 'light');
};
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
}
// Custom hook for consuming context
function useTheme() {
const context = useContext(ThemeContext);
if (!context) {
throw new Error('useTheme must be used within ThemeProvider');
}
return context;
}
// Usage in component
function ThemedButton() {
const { theme, toggleTheme } = useTheme();
return <button onClick={toggleTheme}>{theme}</button>;
}
import { useRef, useEffect } from 'react';
function TextInput() {
// DOM reference
const inputRef = useRef(null);
// Mutable value that persists
const renderCount = useRef(0);
useEffect(() => {
inputRef.current.focus(); // Access DOM element
renderCount.current += 1;
});
return <input ref={inputRef} />;
}
import { useMemo, useCallback } from 'react';
function ExpensiveComponent({ items, onItemClick }) {
// Memoize expensive computation
const sortedItems = useMemo(() => {
return [...items].sort((a, b) => a.name.localeCompare(b.name));
}, [items]);
// Memoize callback function
const handleClick = useCallback((id) => {
onItemClick(id);
}, [onItemClick]);
return (
<ul>
{sortedItems.map(item => (
<li key={item.id} onClick={() => handleClick(item.id)}>
{item.name}
</li>
))}
</ul>
);
}
import { useReducer } from 'react';
// Reducer function
function todoReducer(state, action) {
switch (action.type) {
case 'ADD':
return [...state, { id: Date.now(), text: action.text, done: false }];
case 'TOGGLE':
return state.map(todo =>
todo.id === action.id ? { ...todo, done: !todo.done } : todo
);
case 'DELETE':
return state.filter(todo => todo.id !== action.id);
default:
return state;
}
}
function TodoList() {
const [todos, dispatch] = useReducer(todoReducer, []);
return (
<>
<button onClick={() => dispatch({ type: 'ADD', text: 'New todo' })}>
Add
</button>
{todos.map(todo => (
<div key={todo.id}>
<span
style={{ textDecoration: todo.done ? 'line-through' : 'none' }}
onClick={() => dispatch({ type: 'TOGGLE', id: todo.id })}
>
{todo.text}
</span>
<button onClick={() => dispatch({ type: 'DELETE', id: todo.id })}>
Delete
</button>
</div>
))}
</>
);
}
// useLocalStorage hook
function useLocalStorage(key, initialValue) {
const [value, setValue] = useState(() => {
const stored = localStorage.getItem(key);
return stored ? JSON.parse(stored) : initialValue;
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue];
}
// useDebounce hook
function useDebounce(value, delay) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const timer = setTimeout(() => setDebouncedValue(value), delay);
return () => clearTimeout(timer);
}, [value, delay]);
return debouncedValue;
}
// useFetch hook
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const controller = new AbortController();
fetch(url, { signal: controller.signal })
.then(res => res.json())
.then(setData)
.catch(setError)
.finally(() => setLoading(false));
return () => controller.abort();
}, [url]);
return { data, loading, error };
}
function Form() {
const [value, setValue] = useState('');
// Input change
const handleChange = (e) => {
setValue(e.target.value);
};
// Form submit
const handleSubmit = (e) => {
e.preventDefault();
console.log(value);
};
// Click with data
const handleClick = (id) => (e) => {
console.log(id, e);
};
return (
<form onSubmit={handleSubmit}>
<input value={value} onChange={handleChange} />
<button type="submit">Submit</button>
<button onClick={handleClick(123)}>Click</button>
</form>
);
}
function Component({ isLoggedIn, items, user }) {
return (
<>
{/* If condition */}
{isLoggedIn && <Dashboard />}
{/* If-else */}
{isLoggedIn ? <Dashboard /> : <Login />}
{/* Multiple conditions */}
{items.length === 0 && <p>No items</p>}
{items.length > 0 && items.length <= 5 && <p>Few items</p>}
{items.length > 5 && <p>Many items</p>}
{/* Nullish check */}
{user?.name ?? 'Anonymous'}
</>
);
}
function ItemList({ items }) {
return (
<ul>
{items.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
}
// With index (only if items have no stable ID)
function SimpleList({ items }) {
return (
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
);
}