React 19 brought many revolutionary changes for modern development:
// React Compiler - auto-optimization
function Component({ items }) {
return items.map(item => <Item key={item.id} data={item} />);
}
// Actions in forms
function Form() {
async function submitAction(formData) {
await saveData(formData);
}
return <form action={submitAction}>...</form>;
}React 19 is like moving to a new level of development! The React team rethought many approaches and made the framework even more powerful and convenient. 🎉
No more thinking about useMemo and useCallback:
// Previously had to optimize manually
const ExpensiveComponent = memo(({ data, filter }) => {
const filtered = useMemo(() =>
data.filter(item => item.type === filter), [data, filter]
);
const handleClick = useCallback((id) => {
onItemClick(id);
}, [onItemClick]);
return filtered.map(item =>
<Item key={item.id} onClick={handleClick} />
);
});
// Now compiler does this automatically
function ExpensiveComponent({ data, filter }) {
const filtered = data.filter(item => item.type === filter);
const handleClick = (id) => onItemClick(id);
return filtered.map(item =>
<Item key={item.id} onClick={handleClick} />
);
}Simplified forms and loading state handling:
// Simple form with Actions
function ContactForm() {
async function submitForm(formData) {
const result = await fetch('/api/contact', {
method: 'POST',
body: formData
});
if (!result.ok) throw new Error('Submit error');
}
return (
<form action={submitForm}>
<input name="email" type="email" required />
<textarea name="message" required />
<SubmitButton />
</form>
);
}
function SubmitButton() {
const { pending } = useFormStatus();
return (
<button type="submit" disabled={pending}>
{pending ? 'Submitting...' : 'Submit'}
</button>
);
}New hook for async operations:
// Data loading with use
function UserProfile({ userId }) {
const user = use(fetchUser(userId));
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>
);
}
// Conditional context usage
function Component({ showTheme }) {
const theme = showTheme ? use(ThemeContext) : null;
return (
<div style={{ color: theme?.primaryColor }}>
Content
</div>
);
}Instant UI response:
function TodoList({ todos }) {
const [optimisticTodos, addOptimistic] = useOptimistic(
todos,
(state, newTodo) => [...state, { ...newTodo, pending: true }]
);
async function addTodo(formData) {
const title = formData.get('title');
addOptimistic({ id: Date.now(), title });
await saveTodo(title);
}
return (
<form action={addTodo}>
<input name="title" />
<button>Add</button>
{optimisticTodos.map(todo => (
<div key={todo.id} className={todo.pending ? 'pending' : ''}>
{todo.title}
</div>
))}
</form>
);
}Managing title and meta tags directly from components:
function BlogPost({ post }) {
return (
<>
<title>{post.title} - My Blog</title>
<meta name="description" content={post.excerpt} />
<meta property="og:title" content={post.title} />
<article>
<h1>{post.title}</h1>
<p>{post.content}</p>
</article>
</>
);
}
function App() {
return (
<>
<title>Home Page</title>
<meta name="viewport" content="width=device-width" />
<Router>
<Routes>
<Route path="/post/:id" element={<BlogPost />} />
</Routes>
</Router>
</>
);
}Managing async operation state:
function LoginForm() {
const [state, submitAction, isPending] = useActionState(
async (prevState, formData) => {
try {
const result = await login(formData);
return { success: true, user: result.user };
} catch (error) {
return { success: false, error: error.message };
}
},
{ success: null, error: null }
);
return (
<form action={submitAction}>
<input name="email" type="email" />
<input name="password" type="password" />
<button disabled={isPending}>
{isPending ? 'Logging in...' : 'Login'}
</button>
{state.error && <p className="error">{state.error}</p>}
{state.success && <p>Welcome, {state.user.name}!</p>}
</form>
);
}Components that run on the server:
// Server component
async function ProductList() {
const products = await db.products.findMany();
return (
<div>
{products.map(product => (
<ProductCard key={product.id} product={product} />
))}
</div>
);
}
// Client component
'use client';
function ProductCard({ product }) {
const [liked, setLiked] = useState(false);
return (
<div>
<h3>{product.name}</h3>
<button onClick={() => setLiked(!liked)}>
{liked ? '❤️' : '🤍'}
</button>
</div>
);
}React 19 includes many optimizations:
// Automatic memoization
function ExpensiveList({ items, filter }) {
// Compiler automatically optimizes
const filtered = items.filter(item => item.category === filter);
return filtered.map(item => <Item key={item.id} data={item} />);
}
// Improved ref handling
function AutoFocusInput() {
return <input ref={(input) => input?.focus()} />;
}Main changes when upgrading:
// Removed deprecated APIs
// ❌ No longer works
import { render } from 'react-dom';
// ✅ Use instead
import { createRoot } from 'react-dom/client';
// New ref rules
// ❌ Deprecated
<input ref="myInput" />
// ✅ Modern approach
<input ref={inputRef} />❌ Wrong:
// Manual optimization with compiler
const memoized = useMemo(() => expensive(data), [data]);✅ Correct:
// Let compiler optimize
const result = expensive(data);React 19 is a revolution in development:
Upgrade and enjoy the new possibilities! 🎯