JavaRush /Курсы /Модуль 3: React /Типизация компонентов для React.lazy

Типизация компонентов для React.lazy

Модуль 3: React
10 уровень , 4 лекция
Открыта

Как работает React.lazy?

React.lazy позволяет загружать компоненты лениво, только тогда, когда они действительно нужны. Это особенно полезно, когда ваш код включает в себя крупные библиотеки или части, которые не используются сразу.

Пример:

import React, { Suspense } from 'react';

// Лениво загружаем компонент
const LazyComponent = React.lazy(() => import('./LazyComponent'));

export const App: React.FC = () => {
  return (
    <Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
);
};

В этом примере LazyComponent будет загружен динамически во время рендеринга. Пока компонент загружается, React показывает fallback загрузочный индикатор.

Теперь давайте разберёмся, как к этому всему добавить типизацию.

Типизация компонентов для React.lazy

1. Базовый пример типизации

Когда мы используем React.lazy, важно, чтобы типы загружаемого компонента совпадали с тем, что вы ожидаете в коде. Вот пример правильной типизации:

import React, { Suspense } from 'react';

// Интерфейс для пропсов компонента
interface LazyComponentProps {
  title: string;
  count: number;
}

// Лениво загружаем компонент, определяя его тип
const LazyComponent = React.lazy<React.FC<LazyComponentProps>>(() => import('./LazyComponent'));

export const App: React.FC = () => {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <LazyComponent title="Hello World" count={42} />
    </Suspense>
  );
};

Здесь мы явно указываем React.lazy<React.FC<LazyComponentProps>>, чтобы типизировать компонент. Если кто-то попробует передать пропсы, которые не соответствуют LazyComponentProps, TypeScript сразу предупредит об ошибке.

2. Типизация с использованием default export

Очень часто компоненты, созданные для ленивой загрузки, экспортируются как default. В этом случае важно убедиться, что они обладают требуемым типом:

// LazyComponent.tsx
import React from 'react';

interface LazyComponentProps {
  message: string;
}

const LazyComponent: React.FC<LazyComponentProps> = ({ message }) => {
  return <div>{message}</div>;
};

export default LazyComponent;
// App.tsx
import React, { Suspense } from 'react';

// Типизируем ленивую загрузку компонента
const LazyComponent = React.lazy(() => import('./LazyComponent'));

export const App: React.FC = () => {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <LazyComponent message="Dynamic Component Loaded!" />
    </Suspense>
  );
};

Здесь TypeScript автоматически определяет тип через экспорт по умолчанию, но при необходимости вы можете уточнить его явно.

3. Типизация с использованием named exports

Если ваш компонент экспортируется по имени named export, вам придётся указать точный экспорт при использовании React.lazy:

// LazyComponent.tsx
import React from 'react';

interface LazyComponentProps {
  title: string;
}

export const LazyComponent: React.FC<LazyComponentProps> = ({ title }) => {
  return <h1>{title}</h1>;
};
// App.tsx
import React, { Suspense } from 'react';

// Ленивый импорт конкретного компонента
const LazyComponent = React.lazy(() =>
  import('./LazyComponent').then((module) => ({ default: module.LazyComponent }))
);

export const App: React.FC = () => {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <LazyComponent title="Named Export Component" />
    </Suspense>
  );
};

Здесь требуется указать default в объекте, так как React.lazy ожидает, что загружаемый модуль экспортирует компонент по умолчанию.

4. Обработка ошибок при загрузке

При работе с ленивой загрузкой возможны ошибки загрузки компонентов, например, когда файл не найден или сервер вернул ошибку. В таких случаях важно, чтобы ваше приложение корректно обрабатывало эти ситуации.

import React, { Suspense, lazy } from 'react';

// Типизируем лениво загружаемый компонент
const LazyComponent = lazy(() => import('./LazyComponent').catch((error) => {
  console.error('Error loading LazyComponent:', error);
  return { default: () => <div>Error loading component</div> };
}));

export const App: React.FC = () => {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <LazyComponent />
    </Suspense>
  );
};

В этом примере мы добавили обработку ошибок внутри React.lazy. Если компонент не может быть загружен, вместо него будет показан компонент с сообщением об ошибке.

5. Упрощение типизации с фабриками компонентов

Если вам приходится много работать с ленивыми компонентами, можно создать вспомогательную функцию для упрощения типизации:

import React from 'react';

// Фабрика для ленивой загрузки компонентов
const lazyWithProps = <P extends object>(factory: () => Promise<{ default: React.ComponentType<P> }>) =>
  React.lazy(factory);

interface LazyComponentProps {
  text: string;
}

const LazyComponent = lazyWithProps<LazyComponentProps>(() => import('./LazyComponent'));

export const App: React.FC = () => {
  return (
    <React.Suspense fallback={<div>Loading...</div>}>
      <LazyComponent text="Hello from factory!" />
    </React.Suspense>
  );
};

Эта фабрика помогает избежать повторения кода и обеспечивает строгую типизацию для всех ленивых компонентов.

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

  1. Ошибка типов пропсов: если указать неправильные пропсы для ленивого компонента, TypeScript сразу выдаст предупреждение, но без типизации вы можете получить ошибку только в момент рендеринга.
  2. Отсутствие fallback: не забывайте всегда добавлять fallback в Suspense, чтобы приложение не зависало в случае долгой загрузки.
  3. Неправильный импорт: для named exports помните, что модуль должен быть преобразован в объект с default.
1
Задача
Модуль 3: React, 10 уровень, 4 лекция
Недоступна
Ленивый импорт компонента с типизацией пропсов
Ленивый импорт компонента с типизацией пропсов
1
Задача
Модуль 3: React, 10 уровень, 4 лекция
Недоступна
Ленивый импорт с named export
Ленивый импорт с named export
3
Опрос
Основы оптимизации производительности, 10 уровень, 4 лекция
Недоступен
Основы оптимизации производительности
Основы оптимизации производительности
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ