Skip to content

Commit 4a9eaa0

Browse files
committed
feat: converted component to hooks API, closes #49
1 parent 25ad0c5 commit 4a9eaa0

File tree

6 files changed

+17
-200
lines changed

6 files changed

+17
-200
lines changed

components/react/package.dist.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
"unpkg": "particles.min.js",
8989
"jsdelivr": "particles.min.js",
9090
"peerDependencies": {
91-
"react": ">=16"
91+
"react": ">=16.8.0"
9292
},
9393
"dependencies": {
9494
"@tsparticles/engine": "^3.0.0-beta.1"

components/react/src/IParticlesProps.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,9 @@ import type { CSSProperties } from "react";
33

44
export interface IParticlesProps {
55
id?: string;
6-
width?: string;
7-
height?: string;
86
options?: ISourceOptions;
97
url?: string;
108
style?: CSSProperties;
119
className?: string;
12-
canvasClassName?: string;
1310
particlesLoaded?: (container?: Container) => Promise<void>;
1411
}

components/react/src/IParticlesState.ts

Lines changed: 0 additions & 6 deletions
This file was deleted.

components/react/src/Particles.tsx

Lines changed: 16 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,130 +1,24 @@
1-
import React, { Component, ReactNode } from "react";
2-
import { tsParticles } from "@tsparticles/engine";
1+
import React, { useEffect } from "react";
32
import type { IParticlesProps } from "./IParticlesProps";
4-
import type { IParticlesState } from "./IParticlesState";
5-
import { deepCompare } from "./Utils";
3+
import { tsParticles, type Container } from "@tsparticles/engine";
64

7-
const defaultId = "tsparticles";
5+
function Particles(props: IParticlesProps): JSX.Element {
6+
const id = props.id ?? "tsparticles";
7+
const [container, setContainer] = React.useState<Container | undefined>(undefined);
88

9-
/**
10-
* @param {{id?: string,width?: string,height?: string,options?: import("@tsparticles/engine").ISourceOptions,params?: import("@tsparticles/engine").ISourceOptions,style?: import("react").CSSProperties,className?: string,canvasClassName?: string,container?: RefObject<Container>}}
11-
*/
12-
export default class Particles extends Component<IParticlesProps, IParticlesState> {
13-
static defaultProps: IParticlesProps = {
14-
width: "100%",
15-
height: "100%",
16-
options: {},
17-
style: {},
18-
url: undefined,
19-
id: defaultId,
20-
};
9+
useEffect(() => {
10+
tsParticles.load({ id, url: props.url, options: props.options }).then(c => {
11+
setContainer(c);
2112

22-
constructor(props: IParticlesProps) {
23-
super(props);
24-
25-
this.state = {
26-
init: false,
27-
library: undefined,
28-
};
29-
}
30-
31-
destroy(): void {
32-
if (!this.state.library) {
33-
return;
34-
}
35-
36-
this.state.library.destroy();
37-
38-
this.setState({
39-
library: undefined,
13+
props.particlesLoaded?.(c);
4014
});
41-
}
42-
43-
shouldComponentUpdate(nextProps: Readonly<IParticlesProps>): boolean {
44-
const nextOptions = nextProps.options,
45-
currentOptions = this.props.options;
46-
47-
return (
48-
nextProps.url !== this.props.url ||
49-
nextProps.id !== this.props.id ||
50-
nextProps.canvasClassName !== this.props.canvasClassName ||
51-
nextProps.className !== this.props.className ||
52-
nextProps.height !== this.props.height ||
53-
nextProps.width !== this.props.width ||
54-
!deepCompare(nextProps.style, this.props.style) ||
55-
nextProps.particlesLoaded !== this.props.particlesLoaded ||
56-
!deepCompare(nextOptions, currentOptions, key => key.startsWith("_"))
57-
);
58-
}
59-
60-
componentDidUpdate(): void {
61-
this.refresh();
62-
}
63-
64-
forceUpdate(): void {
65-
this.refresh().then(() => {
66-
super.forceUpdate();
67-
});
68-
}
69-
70-
componentDidMount(): void {
71-
(async () => {
72-
this.setState(
73-
{
74-
init: true,
75-
},
76-
async () => {
77-
await this.loadParticles();
78-
},
79-
);
80-
})();
81-
}
8215

83-
componentWillUnmount(): void {
84-
this.destroy();
85-
}
86-
87-
render(): ReactNode {
88-
const { width, height, className, canvasClassName, id } = this.props;
89-
90-
return (
91-
<div className={className} id={id}>
92-
<canvas
93-
className={canvasClassName}
94-
style={{
95-
...this.props.style,
96-
width,
97-
height,
98-
}}
99-
/>
100-
</div>
101-
);
102-
}
103-
104-
private async refresh(): Promise<void> {
105-
this.destroy();
106-
107-
await this.loadParticles();
108-
}
109-
110-
private async loadParticles(): Promise<void> {
111-
if (!this.state.init) {
112-
return;
113-
}
114-
115-
const id = this.props.id ?? Particles.defaultProps.id ?? defaultId,
116-
container = await tsParticles.load({
117-
url: this.props.url,
118-
id,
119-
options: this.props.options,
120-
});
121-
122-
this.setState({
123-
library: container,
124-
});
16+
return () => {
17+
container?.destroy();
18+
};
19+
}, []);
12520

126-
if (this.props.particlesLoaded) {
127-
await this.props.particlesLoaded(container);
128-
}
129-
}
21+
return <div id={id} className={props.className}></div>;
13022
}
23+
24+
export default Particles;

components/react/src/Utils.ts

Lines changed: 0 additions & 67 deletions
This file was deleted.

components/react/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import Particles from "./Particles";
33
import { useEffect, useState } from "react";
44

55
export type { IParticlesProps, IParticlesProps as ParticlesProps } from "./IParticlesProps";
6-
export type { IParticlesState, IParticlesState as ParticlesState } from "./IParticlesState";
76

87
export function useParticlesPlugins(cb: (engine: Engine) => Promise<void>): { done: boolean; error: boolean } {
98
const [done, setDone] = useState(false),

0 commit comments

Comments
 (0)