Skip to content

Commit 314ccf9

Browse files
committed
chore(package): using custom deep equal function
1 parent 95718a6 commit 314ccf9

File tree

4 files changed

+90
-22
lines changed

4 files changed

+90
-22
lines changed

components/react/package.dist.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@
9191
"react": ">=16"
9292
},
9393
"dependencies": {
94-
"deep-eql": "^4.1.3",
9594
"tsparticles-engine": "^2.11.0"
9695
}
97-
}
96+
}

components/react/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@
110110
"types": "dist/types/index.d.ts",
111111
"prettier": "@tsparticles/prettier-config",
112112
"dependencies": {
113-
"deep-eql": "^4.1.3",
114113
"react": "^18.2.0",
115114
"tsparticles-engine": "^2.11.0"
116115
},

components/react/src/Particles.tsx

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import React, { Component, MutableRefObject, ReactNode } from "react";
2-
import { tsParticles, Container } from "tsparticles-engine";
3-
import equal from "deep-eql";
2+
import { tsParticles, type Container } from "tsparticles-engine";
43
import type { IParticlesProps } from "./IParticlesProps";
54
import type { IParticlesState } from "./IParticlesState";
5+
import { deepCompare } from "./Utils";
66

77
const defaultId = "tsparticles";
88

@@ -41,7 +41,17 @@ export default class Particles extends Component<IParticlesProps, IParticlesStat
4141
}
4242

4343
shouldComponentUpdate(nextProps: Readonly<IParticlesProps>): boolean {
44-
return !equal(nextProps, this.props);
44+
return nextProps.url !== this.props.url &&
45+
nextProps.id !== this.props.id &&
46+
nextProps.canvasClassName !== this.props.canvasClassName &&
47+
nextProps.className !== this.props.className &&
48+
nextProps.height !== this.props.height &&
49+
nextProps.width !== this.props.width &&
50+
!deepCompare(nextProps.style, this.props.style) &&
51+
nextProps.init !== this.props.init &&
52+
nextProps.loaded !== this.props.loaded &&
53+
nextProps &&
54+
!deepCompare(nextProps.options ?? nextProps.params, this.props.options && this.props.params);
4555
}
4656

4757
componentDidUpdate(): void {
@@ -103,25 +113,23 @@ export default class Particles extends Component<IParticlesProps, IParticlesStat
103113
return;
104114
}
105115

106-
const cb = async (container?: Container) => {
107-
if (this.props.container) {
108-
(this.props.container as MutableRefObject<Container | undefined>).current = container;
109-
}
110-
111-
this.setState({
112-
library: container,
116+
const id = this.props.id ?? Particles.defaultProps.id ?? defaultId,
117+
container = await tsParticles.load({
118+
url: this.props.url,
119+
id,
120+
options: this.props.options ?? this.props.params,
113121
});
114122

115-
if (this.props.loaded) {
116-
await this.props.loaded(container);
117-
}
118-
};
123+
if (this.props.container) {
124+
(this.props.container as MutableRefObject<Container | undefined>).current = container;
125+
}
119126

120-
const id = this.props.id ?? Particles.defaultProps.id ?? defaultId,
121-
container = this.props.url
122-
? await tsParticles.loadJSON(id, this.props.url)
123-
: await tsParticles.load(id, this.props.options ?? this.props.params);
127+
this.setState({
128+
library: container,
129+
});
124130

125-
await cb(container);
131+
if (this.props.loaded) {
132+
await this.props.loaded(container);
133+
}
126134
}
127135
}

components/react/src/Utils.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
const isObject = (val: unknown): val is object => typeof val === "object" && val !== null;
2+
3+
export function deepCompare(obj1: unknown, obj2: unknown, excludedKeys: string[] = []): boolean {
4+
if (!isObject(obj1) || !isObject(obj2)) {
5+
return obj1 === obj2;
6+
}
7+
8+
const keys1 = Object.keys(obj1).filter((key) => !excludedKeys.includes(key)),
9+
keys2 = Object.keys(obj2).filter((key) => !excludedKeys.includes(key));
10+
11+
if (keys1.length !== keys2.length) {
12+
return false;
13+
}
14+
15+
for (const key of keys1) {
16+
const value1: unknown = (obj1 as Record<string, unknown>)[key],
17+
value2: unknown = (obj2 as Record<string, unknown>)[key];
18+
19+
if (isObject(value1) && isObject(value2)) {
20+
// Handle circular references
21+
if (value1 === obj2 && value2 === obj1) {
22+
continue;
23+
}
24+
25+
if (!deepCompare(value1, value2, excludedKeys)) {
26+
return false;
27+
}
28+
} else if (Array.isArray(value1) && Array.isArray(value2)) {
29+
if (!deepCompareArrays(value1, value2, excludedKeys)) {
30+
return false;
31+
}
32+
} else if (value1 !== value2) {
33+
return false;
34+
}
35+
}
36+
37+
return true;
38+
}
39+
40+
function deepCompareArrays(arr1: unknown[], arr2: unknown[], excludedKeys: string[]): boolean {
41+
if (arr1.length !== arr2.length) {
42+
return false;
43+
}
44+
45+
for (let i = 0; i < arr1.length; i++) {
46+
const val1 = arr1[i], val2 = arr2[i];
47+
48+
if (Array.isArray(val1) && Array.isArray(val2)) {
49+
if (!deepCompareArrays(val1, val2, excludedKeys)) {
50+
return false;
51+
}
52+
} else if (isObject(val1) && isObject(val2)) {
53+
if (!deepCompare(val1, val2, excludedKeys)) {
54+
return false;
55+
}
56+
} else if (val1 !== val2) {
57+
return false;
58+
}
59+
}
60+
61+
return true;
62+
}

0 commit comments

Comments
 (0)