React Immutable Pure Component

2.2.2 · active · verified Sun Apr 19

This library provides `ImmutablePureComponent`, an enhanced React PureComponent specifically designed to work efficiently with Immutable.js data structures. It addresses the limitation of React's built-in `PureComponent` which doesn't fully leverage Immutable.js's structural sharing for shallow comparisons. The core mechanism involves `updateOnProps` and `updateOnStates` properties, allowing developers to explicitly define which specific props or state paths should trigger re-renders, using `Immutable.is` for deep equality checks on specified paths. The current stable version is 2.2.2. Releases have been somewhat sporadic, but updates address typings, dependency changes, and new features like `immutableMemo`. Its key differentiator is providing granular control over `Immutable.js`-aware re-rendering logic within a class component context, offering an alternative to `React.memo` with Immutable.js. It supports both class and functional components (via `immutableMemo`) and ships with TypeScript types.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates both `ImmutablePureComponent` (class-based) and `immutableMemo` (functional) to optimize React re-renders with Immutable.js data. It shows how to define `updateOnProps` and `updateOnStates` to control component updates based on Immutable.js structural equality.

import React, { useState, useCallback } from 'react';
import { ImmutablePureComponent, immutableMemo } from 'react-immutable-pure-component';
import { Map, List } from 'immutable';

// A class component using ImmutablePureComponent
class MyClassComponent extends ImmutablePureComponent<{ data: Map<string, any>, label: string }, { count: number }> {
  // Specify props to check for updates using Immutable.is
  updateOnProps = ['data'];
  // Specify state keys to check for updates
  updateOnStates = ['count'];

  constructor(props: any) {
    super(props);
    this.state = { count: 0 };
  }

  componentDidMount() {
    // Example: Update internal state after some time
    setTimeout(() => {
      this.setState({ count: 1 });
    }, 1000);
  }

  render() {
    console.log(`MyClassComponent (${this.props.label}) rendered`);
    return (
      <div>
        <h3>Class Component: {this.props.label}</h3>
        <p>Data Version: {this.props.data.get('version')}</p>
        <p>Internal Count: {this.state.count}</p>
      </div>
    );
  }
}

// A functional component using immutableMemo
interface MyFuncProps {
  items: List<string>;
  onClick: (item: string) => void;
}

const MyFunctionalComponent = immutableMemo<MyFuncProps>(({ items, onClick }) => {
  console.log('MyFunctionalComponent rendered');
  return (
    <div>
      <h3>Functional Component</h3>
      <ul>
        {items.map((item, index) => (
          <li key={index} onClick={() => onClick(item)}>{item}</li>
        ))}
      </ul>
    </div>
  );
}, ['items']); // 'items' array specifies props to compare with Immutable.is

const App = () => {
  const [data, setData] = useState(Map({ version: 1 }));
  const [items, setItems] = useState(List(['Apple', 'Banana']));

  const updateData = () => {
    // Only updates if the new Map is structurally different on specified keys
    setData(data => data.set('version', data.get('version') + 1));
  };

  const handleItemClick = useCallback((item: string) => {
    console.log(`Clicked: ${item}`);
  }, []);

  return (
    <div>
      <h1>React Immutable Pure Component Demo</h1>
      <button onClick={updateData}>Update Data Version</button>
      <MyClassComponent data={data} label="Example 1" />
      {/* This component will only re-render if 'data' specifically changes (version increments) */}

      <MyFunctionalComponent items={items} onClick={handleItemClick} />
      {/* This component will only re-render if 'items' List changes structurally */}
    </div>
  );
};

export default App;

view raw JSON →