Skip to content

Commit 19b306d

Browse files
committed
Remove useEffectOnce, store canvas into state to support react 18 mount-unmount-mount in development
1 parent 9b99037 commit 19b306d

2 files changed

Lines changed: 36 additions & 62 deletions

File tree

src/Canvas.tsx

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
import React, { useEffect, useRef } from 'react';
2-
import { FiberRoot } from 'react-reconciler';
1+
import React, { useEffect, useRef, useState } from 'react';
32
import { ConcurrentRoot } from 'react-reconciler/constants';
3+
import { FiberRoot } from 'react-reconciler';
44
import { PaperScope } from 'paper/dist/paper-core';
5-
65
import { Renderer } from './Renderer';
7-
import { useEffectOnce } from './useEffectOnce';
86

97
type PaperScopeSettings = {
108
insertItems?: boolean;
@@ -28,21 +26,22 @@ export const Canvas = ({
2826
onScopeReady,
2927
...other
3028
}: Props) => {
31-
const canvas = useRef<HTMLCanvasElement | null>(null);
32-
const scope = useRef<paper.PaperScope | null>(null);
33-
const fiber = useRef<FiberRoot | null>(null);
29+
const [canvas, setCanvas] = useState<HTMLCanvasElement | null>(null);
30+
const canvasRef = useRef<HTMLCanvasElement | null>(null);
31+
const scopeRef = useRef<paper.PaperScope | null>(null);
32+
const fiberRef = useRef<FiberRoot | null>(null);
3433

35-
useEffectOnce(() => {
34+
useEffect(() => {
3635
// create
37-
if (canvas.current instanceof HTMLCanvasElement) {
38-
scope.current = new PaperScope();
39-
Object.assign(scope.current.settings, {
36+
if (canvas instanceof HTMLCanvasElement) {
37+
scopeRef.current = new PaperScope();
38+
Object.assign(scopeRef.current.settings, {
4039
...settings,
4140
insertItems: false,
4241
});
43-
scope.current.setup(canvas.current);
44-
fiber.current = Renderer.createContainer(
45-
scope.current,
42+
scopeRef.current.setup(canvas);
43+
fiberRef.current = Renderer.createContainer(
44+
scopeRef.current,
4645
ConcurrentRoot,
4746
null,
4847
false,
@@ -51,36 +50,44 @@ export const Canvas = ({
5150
console.error,
5251
null
5352
);
54-
Renderer.updateContainer(null, fiber.current, null, () => null);
53+
Renderer.updateContainer(null, fiberRef.current, null, () => null);
5554
if (typeof onScopeReady === 'function') {
56-
onScopeReady(scope.current);
55+
onScopeReady(scopeRef.current);
5756
}
5857
}
5958

6059
// destroy
6160
return () => {
62-
if (fiber.current) {
63-
Renderer.updateContainer(null, fiber.current, null, () => null);
61+
if (canvas) {
62+
if (fiberRef.current) {
63+
Renderer.updateContainer(null, fiberRef.current, null, () => null);
64+
}
65+
scopeRef.current = null;
66+
canvasRef.current = null;
67+
fiberRef.current = null;
6468
}
65-
canvas.current = null;
66-
scope.current = null;
67-
fiber.current = null;
6869
};
69-
});
70+
// eslint-disable-next-line react-hooks/exhaustive-deps
71+
}, [canvas]);
7072

7173
// update
7274
useEffect(() => {
73-
if (scope.current && fiber.current) {
74-
Renderer.updateContainer(children, fiber.current, null, () => null);
75+
if (scopeRef.current && fiberRef.current) {
76+
Renderer.updateContainer(children, fiberRef.current, null, () => null);
7577
}
76-
}, [children]);
78+
}, [canvas, children]);
7779

7880
// resize
7981
useEffect(() => {
80-
if (scope.current) {
81-
scope.current.view.viewSize = new scope.current.Size(width, height);
82+
if (scopeRef.current) {
83+
scopeRef.current.view.viewSize = new scopeRef.current.Size(width, height);
8284
}
83-
}, [width, height]);
85+
}, [canvas, width, height]);
86+
87+
// mounted
88+
useEffect(() => {
89+
setCanvas(canvasRef.current);
90+
}, []);
8491

85-
return <canvas {...other} ref={canvas} />;
92+
return <canvas {...other} ref={canvasRef} />;
8693
};

src/useEffectOnce.tsx

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

0 commit comments

Comments
 (0)