or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-react-fast-compare

Fastest deep equal comparison for React with optimizations for React elements and circular reference handling

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/react-fast-compare@3.2.x

To install, run

npx @tessl/cli install tessl/npm-react-fast-compare@3.2.0

0

# React Fast Compare

1

2

React Fast Compare provides the fastest deep equal comparison for React applications, with optimizations for React elements and built-in circular reference handling. It offers a single unified entry point that handles React-specific circular references like React elements, includes try/catch guardrails for stack overflows, and supports all JavaScript data types.

3

4

## Package Information

5

6

- **Package Name**: react-fast-compare

7

- **Package Type**: npm

8

- **Language**: JavaScript (with TypeScript definitions)

9

- **Installation**: `npm install react-fast-compare` or `yarn add react-fast-compare`

10

11

## Core Imports

12

13

```javascript

14

const isEqual = require('react-fast-compare');

15

```

16

17

For ES modules/TypeScript:

18

19

```typescript

20

import isEqual = require('react-fast-compare');

21

```

22

23

## Basic Usage

24

25

```javascript

26

const isEqual = require('react-fast-compare');

27

28

// General deep comparison

29

console.log(isEqual({ foo: 'bar' }, { foo: 'bar' })); // true

30

console.log(isEqual([1, 2, 3], [1, 2, 3])); // true

31

32

// React.memo usage

33

const MemoComponent = React.memo(ExpensiveComponent, isEqual);

34

35

// shouldComponentUpdate usage

36

class Component extends React.Component {

37

shouldComponentUpdate(nextProps) {

38

return !isEqual(this.props, nextProps);

39

}

40

}

41

42

// React-Redux useSelector usage

43

const value = useSelector(selector, isEqual);

44

```

45

46

## Capabilities

47

48

### Deep Equality Comparison

49

50

Performs deep equality comparison optimized for React applications with circular reference handling.

51

52

```typescript { .api }

53

/**

54

* Compare two values for deep equality with React-specific optimizations

55

* @param a - First value to compare

56

* @param b - Second value to compare

57

* @returns true if values are deeply equal, false otherwise

58

*/

59

function isEqual<A = any, B = any>(a: A, b: B): boolean;

60

```

61

62

**Supported Data Types:**

63

- **Primitives**: string, number, boolean, null, undefined, symbol, bigint

64

- **Objects**: Plain objects, arrays

65

- **Built-in Objects**: Date, RegExp, Map, Set, ArrayBuffer views (typed arrays)

66

- **React Elements**: Special handling for React/Preact elements with circular reference avoidance

67

- **DOM Elements**: Special handling for DOM Element instances

68

69

**React-Specific Features:**

70

- **Circular Reference Handling**: Automatically skips `_owner`, `__v`, `__o` properties in React/Preact elements to avoid infinite loops

71

- **Element Comparison**: DOM Element instances always return false (different elements are never equal)

72

- **Stack Overflow Protection**: Catches stack overflow errors from undetected circular references and returns false with console warning

73

74

**Error Handling:**

75

- **Circular References**: Returns `false` and logs "react-fast-compare cannot handle circular refs" warning

76

- **Stack Overflow**: Detects stack/recursion errors and safely returns `false`

77

- **Other Errors**: Re-throws unexpected errors for proper debugging

78

79

**Performance Characteristics:**

80

- **ES5 Compatible**: Works in IE9+ and Node.js 0.10+

81

- **Bundle Size**: 656 bytes minified+gzipped

82

- **Speed**: Comparable to fast-deep-equal for general data, optimized for React use cases

83

84

**Usage Examples:**

85

86

```javascript

87

// Basic object comparison

88

isEqual({ name: 'Alice', age: 25 }, { name: 'Alice', age: 25 }); // true

89

isEqual({ name: 'Alice' }, { name: 'Bob' }); // false

90

91

// Array comparison

92

isEqual([1, 2, [3, 4]], [1, 2, [3, 4]]); // true

93

isEqual([1, 2, 3], [1, 2, 4]); // false

94

95

// Date comparison

96

isEqual(new Date('2023-01-01'), new Date('2023-01-01')); // true

97

isEqual(new Date('2023-01-01'), new Date('2023-01-02')); // false

98

99

// RegExp comparison

100

isEqual(/abc/gi, /abc/gi); // true

101

isEqual(/abc/g, /abc/i); // false

102

103

// Map comparison

104

const map1 = new Map([['a', 1], ['b', 2]]);

105

const map2 = new Map([['a', 1], ['b', 2]]);

106

isEqual(map1, map2); // true

107

108

// Set comparison

109

const set1 = new Set([1, 2, 3]);

110

const set2 = new Set([1, 2, 3]);

111

isEqual(set1, set2); // true

112

113

// React element comparison (skips circular references)

114

const element1 = React.createElement('div', { id: 'test' }, 'Hello');

115

const element2 = React.createElement('div', { id: 'test' }, 'Hello');

116

isEqual(element1, element2); // true (ignores _owner and other circular props)

117

118

// Typed array comparison

119

const arr1 = new Uint8Array([1, 2, 3]);

120

const arr2 = new Uint8Array([1, 2, 3]);

121

isEqual(arr1, arr2); // true

122

```

123

124

**Integration Examples:**

125

126

```typescript

127

// React.memo with custom comparison

128

interface Props {

129

data: ComplexObject;

130

config: ConfigObject;

131

}

132

133

const OptimizedComponent = React.memo<Props>(({ data, config }) => {

134

// Expensive component logic

135

return <div>{/* Complex UI */}</div>;

136

}, isEqual);

137

138

// Class component shouldComponentUpdate

139

class ExpensiveList extends React.Component<ListProps> {

140

shouldComponentUpdate(nextProps: ListProps) {

141

// Only re-render if props actually changed

142

return !isEqual(this.props, nextProps);

143

}

144

145

render() {

146

return (

147

<ul>

148

{this.props.items.map(item =>

149

<li key={item.id}>{item.name}</li>

150

)}

151

</ul>

152

);

153

}

154

}

155

156

// React-Redux useSelector with equality check

157

const selectUserData = (state: RootState) => ({

158

user: state.user,

159

preferences: state.preferences,

160

settings: state.settings

161

});

162

163

function UserProfile() {

164

// Prevents unnecessary re-renders when reference changes but content is same

165

const userData = useSelector(selectUserData, isEqual);

166

167

return <div>{userData.user.name}</div>;

168

}

169

```