Что нового в React 19?

👨‍💻 Frontend Developer 🟠 Может встретиться 🎚️ Средний
#React

Краткий ответ

React 19 принёс множество революционных изменений для современной разработки:

  1. React Compiler — автоматическая оптимизация без useMemo/useCallback 🚀
  2. Actions — упрощённая работа с формами и асинхронными операциями 📝
  3. use Hook — новый хук для работы с промисами и контекстом 🔄
  4. Server Components — стабильная версия серверных компонентов 🖥️
  5. Document Metadata — встроенная поддержка title и meta тегов 📄
  6. Web Components — улучшенная интеграция с веб-компонентами 🔗
  7. Новые хуки — useOptimistic, useFormStatus, useActionState 🎯
// 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 переосмыслила многие подходы и сделала фреймворк ещё более мощным и удобным. 🎉

1. React Compiler — автоматическая оптимизация

Больше не нужно думать о 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} />
  );
}

2. Actions — новый подход к формам

Упрощённая работа с формами и состоянием загрузки:

// Простая форма с 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>
  );
}

3. use Hook — работа с промисами

Новый хук для асинхронных операций:

// Загрузка данных с 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>
  );
}

4. useOptimistic — оптимистичные обновления

Мгновенный отклик интерфейса:

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>
  );
}

5. Document Metadata — встроенные мета-теги

Управление заголовком и мета-тегами прямо из компонентов:

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>
    </>
  );
}

6. useActionState — состояние действий

Управление состоянием асинхронных операций:

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>
  );
}

7. Server Components — стабильная версия

Компоненты, которые выполняются на сервере:

// Серверный компонент
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()} />;
}

Миграция с React 18

Основные изменения при обновлении:

// Удалены устаревшие API
// ❌ Больше не работает
import { render } from 'react-dom';
 
// ✅ Используйте
import { createRoot } from 'react-dom/client';
 
// Новые правила для ref
// ❌ Устарело
<input ref="myInput" />
 
// ✅ Современный подход
<input ref={inputRef} />

Лучшие практики

  1. Используйте Actions для форм вместо useState 📝
  2. Применяйте use Hook для асинхронных данных 🔄
  3. Доверьтесь компилятору — уберите лишние оптимизации 🚀
  4. Используйте Server Components для статического контента 🖥️

Частые ошибки

Неправильно:

// Ручная оптимизация с компилятором
const memoized = useMemo(() => expensive(data), [data]);

Правильно:

// Позвольте компилятору оптимизировать
const result = expensive(data);

Заключение

React 19 — это революция в разработке:

  • Компилятор автоматизирует оптимизации
  • Actions упрощают работу с формами
  • Новые хуки решают типичные задачи
  • Server Components улучшают производительность

Обновляйтесь и наслаждайтесь новыми возможностями! 🎯