React 19 принёс множество революционных изменений для современной разработки:
// React Compiler - автооптимизация
function Component({ items }) {
return items.map(item => <Item key={item.id} data={item} />);
}
// Actions в формах
function Form() {
async function submitAction(formData) {
await saveData(formData);
}
return <form action={submitAction}>...</form>;
}React 19 — это как переход на новый уровень разработки! Команда React переосмыслила многие подходы и сделала фреймворк ещё более мощным и удобным. 🎉
Больше не нужно думать о useMemo и useCallback:
// Раньше приходилось оптимизировать вручную
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} />
);
});
// Теперь компилятор делает это автоматически
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} />
);
}Упрощённая работа с формами и состоянием загрузки:
// Простая форма с Actions
function ContactForm() {
async function submitForm(formData) {
const result = await fetch('/api/contact', {
method: 'POST',
body: formData
});
if (!result.ok) throw new 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 ? 'Отправка...' : 'Отправить'}
</button>
);
}Новый хук для асинхронных операций:
// Загрузка данных с use
function UserProfile({ userId }) {
const user = use(fetchUser(userId));
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>
);
}
// Условное использование контекста
function Component({ showTheme }) {
const theme = showTheme ? use(ThemeContext) : null;
return (
<div style={{ color: theme?.primaryColor }}>
Контент
</div>
);
}Мгновенный отклик интерфейса:
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>Добавить</button>
{optimisticTodos.map(todo => (
<div key={todo.id} className={todo.pending ? 'pending' : ''}>
{todo.title}
</div>
))}
</form>
);
}Управление заголовком и мета-тегами прямо из компонентов:
function BlogPost({ post }) {
return (
<>
<title>{post.title} - Мой блог</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>Главная страница</title>
<meta name="viewport" content="width=device-width" />
<Router>
<Routes>
<Route path="/post/:id" element={<BlogPost />} />
</Routes>
</Router>
</>
);
}Управление состоянием асинхронных операций:
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 ? 'Вход...' : 'Войти'}
</button>
{state.error && <p className="error">{state.error}</p>}
{state.success && <p>Добро пожаловать, {state.user.name}!</p>}
</form>
);
}Компоненты, которые выполняются на сервере:
// Серверный компонент
async function ProductList() {
const products = await db.products.findMany();
return (
<div>
{products.map(product => (
<ProductCard key={product.id} product={product} />
))}
</div>
);
}
// Клиентский компонент
'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 включает множество оптимизаций:
// Автоматическое мемоизирование
function ExpensiveList({ items, filter }) {
// Компилятор автоматически оптимизирует
const filtered = items.filter(item => item.category === filter);
return filtered.map(item => <Item key={item.id} data={item} />);
}
// Улучшенная работа с ref
function AutoFocusInput() {
return <input ref={(input) => input?.focus()} />;
}Основные изменения при обновлении:
// Удалены устаревшие API
// ❌ Больше не работает
import { render } from 'react-dom';
// ✅ Используйте
import { createRoot } from 'react-dom/client';
// Новые правила для ref
// ❌ Устарело
<input ref="myInput" />
// ✅ Современный подход
<input ref={inputRef} />❌ Неправильно:
// Ручная оптимизация с компилятором
const memoized = useMemo(() => expensive(data), [data]);✅ Правильно:
// Позвольте компилятору оптимизировать
const result = expensive(data);React 19 — это революция в разработке:
Обновляйтесь и наслаждайтесь новыми возможностями! 🎯