CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-loadable

A higher order component for loading components with promises

Pending
Overview
Eval results
Files

dynamic-loading.mddocs/

Dynamic Component Loading

Core functionality for creating loadable components that dynamically load modules before rendering. This enables code splitting at the component level, reducing initial bundle sizes and improving application performance.

Capabilities

Loadable Function

Creates a loadable component that handles dynamic imports with loading states, error handling, and customizable rendering.

/**
 * Creates a higher-order component for dynamic component loading
 * @param options - Configuration object for the loadable component
 * @returns LoadableComponent class
 */
function Loadable(options: LoadableOptions): LoadableComponent;

interface LoadableOptions {
  /** Function that returns a promise resolving to the module */
  loader: () => Promise<any>;
  /** Component to render during loading/error states */
  loading: LoadingComponent;
  /** Delay in milliseconds before showing loading component (default: 200) */
  delay?: number;
  /** Timeout in milliseconds before showing timeout state (default: null) */
  timeout?: number;
  /** Custom render function for the loaded module */
  render?: (loaded: any, props: any) => React.ReactElement;
  /** Function returning webpack module IDs for SSR */
  webpack?: () => number[];
  /** Array of module paths for SSR */
  modules?: string[];
}

Usage Examples:

import React from 'react';
import Loadable from 'react-loadable';

// Simple loadable component
const LoadableButton = Loadable({
  loader: () => import('./Button'),
  loading: () => <div>Loading button...</div>,
});

// Advanced configuration with error handling
const LoadableChart = Loadable({
  loader: () => import('./Chart'),
  loading: LoadingComponent,
  delay: 300,
  timeout: 10000,
  render(loaded, props) {
    const Chart = loaded.default;
    return <Chart {...props} />;
  },
});

function LoadingComponent(props) {
  if (props.error) {
    return <div>Error! <button onClick={props.retry}>Retry</button></div>;
  } else if (props.timedOut) {
    return <div>Taking a long time... <button onClick={props.retry}>Retry</button></div>;
  } else if (props.pastDelay) {
    return <div>Loading...</div>;
  } else {
    return null;
  }
}

LoadableComponent

The component returned by Loadable(), which renders the loading component while the module loads and then renders the loaded component.

/**
 * Component created by Loadable function
 */
interface LoadableComponent extends React.Component {
  /** Static method to preload the component */
  static preload(): Promise<any>;
}

Usage Examples:

// Preload component on user interaction
const LoadableModal = Loadable({
  loader: () => import('./Modal'),
  loading: Loading,
});

function App() {
  const [showModal, setShowModal] = useState(false);

  const handleMouseOver = () => {
    // Preload component when user hovers
    LoadableModal.preload();
  };

  const handleClick = () => {
    setShowModal(true);
  };

  return (
    <div>
      <button onMouseOver={handleMouseOver} onClick={handleClick}>
        Show Modal
      </button>
      {showModal && <LoadableModal onClose={() => setShowModal(false)} />}
    </div>
  );
}

Loading Component Interface

The loading component receives props that describe the current loading state and provide error recovery functionality.

/**
 * Props passed to the loading component
 */
interface LoadingComponentProps {
  /** Whether the module is currently loading */
  isLoading: boolean;
  /** Whether the delay threshold has been exceeded */
  pastDelay: boolean;
  /** Whether the timeout threshold has been exceeded */
  timedOut: boolean;
  /** Error object if loading failed, null otherwise */
  error: Error | null;
  /** Function to retry loading after an error */
  retry: () => void;
}

/**
 * Component type for loading states
 */
type LoadingComponent = React.ComponentType<LoadingComponentProps>;

Usage Examples:

// Comprehensive loading component
function LoadingComponent(props) {
  if (props.error) {
    return (
      <div className="error">
        <p>Failed to load component</p>
        <button onClick={props.retry}>Try Again</button>
      </div>
    );
  }
  
  if (props.timedOut) {
    return (
      <div className="timeout">
        <p>Taking longer than expected...</p>
        <button onClick={props.retry}>Retry</button>
      </div>
    );
  }
  
  if (props.pastDelay) {
    return <div className="loading">Loading...</div>;
  }
  
  return null; // Don't show anything initially
}

// Minimal loading component
const SimpleLoading = (props) => 
  props.error ? <div>Error!</div> : 
  props.pastDelay ? <div>Loading...</div> : null;

Custom Rendering

Customize how the loaded module is rendered using the render option.

/**
 * Custom render function type
 * @param loaded - The resolved module from the loader
 * @param props - Props passed to the LoadableComponent
 * @returns React element to render
 */
type RenderFunction = (loaded: any, props: any) => React.ReactElement;

Usage Examples:

// Render specific export from module
const LoadableIcon = Loadable({
  loader: () => import('./icons'),
  loading: Loading,
  render(loaded, props) {
    const Icon = loaded[props.iconName];
    return <Icon {...props} />;
  },
});

// Add props transformation
const LoadableAPI = Loadable({
  loader: () => import('./APIComponent'),
  loading: Loading,
  render(loaded, props) {
    const APIComponent = loaded.default;
    return <APIComponent {...props} apiKey={process.env.REACT_APP_API_KEY} />;
  },
});

Configuration Options

Delay Configuration

Control when the loading component appears to avoid flash of loading content for fast-loading components.

// Show loading immediately
const LoadableImmediate = Loadable({
  loader: () => import('./Component'),
  loading: Loading,
  delay: 0,
});

// Wait 500ms before showing loading
const LoadableDelayed = Loadable({
  loader: () => import('./Component'),
  loading: Loading,
  delay: 500,
});

Timeout Configuration

Set a timeout for loading operations to handle slow network conditions.

// 5 second timeout
const LoadableWithTimeout = Loadable({
  loader: () => import('./Component'),
  loading: Loading,
  timeout: 5000,
});

Server-Side Rendering Options

Configure webpack and modules options for server-side rendering support.

// Manual configuration (usually automated by Babel plugin)
const LoadableSSR = Loadable({
  loader: () => import('./Component'),
  loading: Loading,
  webpack: () => [require.resolveWeak('./Component')],
  modules: ['./Component'],
});

Install with Tessl CLI

npx tessl i tessl/npm-react-loadable

docs

build-integration.md

dynamic-loading.md

index.md

multi-resource-loading.md

server-side-rendering.md

tile.json