@react-three/fiber 8.0.7 → 8.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -39,6 +39,48 @@ var threeTypes = /*#__PURE__*/Object.freeze({
39
39
  __proto__: null
40
40
  });
41
41
 
42
+ const isOrthographicCamera = def => def && def.isOrthographicCamera; // React currently throws a warning when using useLayoutEffect on the server.
43
+ // To get around it, we can conditionally useEffect on the server (no-op) and
44
+ // useLayoutEffect on the client.
45
+
46
+ const isSSR = typeof window === 'undefined' || !window.navigator || /ServerSideRendering|^Deno\//.test(window.navigator.userAgent);
47
+ const useIsomorphicLayoutEffect = isSSR ? React__namespace.useEffect : React__namespace.useLayoutEffect;
48
+ function useMutableCallback(fn) {
49
+ const ref = React__namespace.useRef(fn);
50
+ useIsomorphicLayoutEffect(() => void (ref.current = fn), [fn]);
51
+ return ref;
52
+ }
53
+ function Block({
54
+ set
55
+ }) {
56
+ useIsomorphicLayoutEffect(() => {
57
+ set(new Promise(() => null));
58
+ return () => set(false);
59
+ }, [set]);
60
+ return null;
61
+ }
62
+ class ErrorBoundary extends React__namespace.Component {
63
+ constructor(...args) {
64
+ super(...args);
65
+ this.state = {
66
+ error: false
67
+ };
68
+ }
69
+
70
+ componentDidCatch(error) {
71
+ this.props.set(error);
72
+ }
73
+
74
+ render() {
75
+ return this.state.error ? null : this.props.children;
76
+ }
77
+
78
+ }
79
+
80
+ ErrorBoundary.getDerivedStateFromError = () => ({
81
+ error: true
82
+ });
83
+
42
84
  const DEFAULT = '__default';
43
85
  const isDiffSet = def => def && !!def.memoized && !!def.changes;
44
86
  function calculateDpr(dpr) {
@@ -211,10 +253,7 @@ function detach(parent, child, type) {
211
253
  target,
212
254
  key
213
255
  } = resolve(parent, type);
214
- const previous = child.__r3f.previousAttach; // When the previous value was undefined, it means the value was never set to begin with
215
-
216
- if (previous === undefined) delete target[key]; // Otherwise set the previous value
217
- else target[key] = previous;
256
+ target[key] = child.__r3f.previousAttach;
218
257
  } else (_child$__r3f = child.__r3f) == null ? void 0 : _child$__r3f.previousAttach == null ? void 0 : _child$__r3f.previousAttach(parent, child);
219
258
 
220
259
  (_child$__r3f2 = child.__r3f) == null ? true : delete _child$__r3f2.previousAttach;
@@ -307,11 +346,9 @@ function applyProps$1(instance, data) {
307
346
  // use the prop constructor to find the default it should be
308
347
  value = new targetProp.constructor(...memoized.args);
309
348
  } else if (currentInstance.constructor) {
310
- var _currentInstance$__r, _currentInstance$__r2;
311
-
312
349
  // create a blank slate of the instance and copy the particular parameter.
313
350
  // @ts-ignore
314
- const defaultClassCall = new currentInstance.constructor(...((_currentInstance$__r = (_currentInstance$__r2 = currentInstance.__r3f) == null ? void 0 : _currentInstance$__r2.memoizedProps.args) != null ? _currentInstance$__r : []));
351
+ const defaultClassCall = new currentInstance.constructor(...currentInstance.__r3f.memoizedProps.args);
315
352
  value = defaultClassCall[targetProp]; // destory the instance
316
353
 
317
354
  if (defaultClassCall.dispose) defaultClassCall.dispose(); // instance does not have constructor, just set it to 0
@@ -380,6 +417,25 @@ function invalidateInstance(instance) {
380
417
  function updateInstance(instance) {
381
418
  instance.onUpdate == null ? void 0 : instance.onUpdate(instance);
382
419
  }
420
+ function updateCamera(camera, size) {
421
+ // https://github.com/pmndrs/react-three-fiber/issues/92
422
+ // Do not mess with the camera if it belongs to the user
423
+ if (!camera.manual) {
424
+ if (isOrthographicCamera(camera)) {
425
+ camera.left = size.width / -2;
426
+ camera.right = size.width / 2;
427
+ camera.top = size.height / 2;
428
+ camera.bottom = size.height / -2;
429
+ } else {
430
+ camera.aspect = size.width / size.height;
431
+ }
432
+
433
+ camera.updateProjectionMatrix(); // https://github.com/pmndrs/react-three-fiber/issues/178
434
+ // Update matrix world since the renderer is a frame late
435
+
436
+ camera.updateMatrixWorld();
437
+ }
438
+ }
383
439
 
384
440
  function makeId(event) {
385
441
  return (event.eventObject || event.object).uuid + '/' + event.index + event.instanceId;
@@ -1153,7 +1209,6 @@ function createRenderer(roots, getEventPriority) {
1153
1209
  }
1154
1210
 
1155
1211
  const isRenderer = def => !!(def != null && def.render);
1156
- const isOrthographicCamera = def => def && def.isOrthographicCamera;
1157
1212
  const context = /*#__PURE__*/React__namespace.createContext(null);
1158
1213
 
1159
1214
  const createStore = (invalidate, advance) => {
@@ -1360,24 +1415,7 @@ const createStore = (invalidate, advance) => {
1360
1415
  } = rootState.getState();
1361
1416
 
1362
1417
  if (size !== oldSize || viewport.dpr !== oldDpr) {
1363
- // https://github.com/pmndrs/react-three-fiber/issues/92
1364
- // Do not mess with the camera if it belongs to the user
1365
- if (!camera.manual) {
1366
- if (isOrthographicCamera(camera)) {
1367
- camera.left = size.width / -2;
1368
- camera.right = size.width / 2;
1369
- camera.top = size.height / 2;
1370
- camera.bottom = size.height / -2;
1371
- } else {
1372
- camera.aspect = size.width / size.height;
1373
- }
1374
-
1375
- camera.updateProjectionMatrix(); // https://github.com/pmndrs/react-three-fiber/issues/178
1376
- // Update matrix world since the renderer is a frame late
1377
-
1378
- camera.updateMatrixWorld();
1379
- } // Update renderer
1380
-
1418
+ updateCamera(camera, size); // Update renderer
1381
1419
 
1382
1420
  gl.setPixelRatio(viewport.dpr);
1383
1421
  gl.setSize(size.width, size.height);
@@ -1401,8 +1439,23 @@ let i;
1401
1439
  let globalEffects = [];
1402
1440
  let globalAfterEffects = [];
1403
1441
  let globalTailEffects = [];
1442
+ /**
1443
+ * Adds a global render callback which is called each frame.
1444
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addEffect
1445
+ */
1446
+
1404
1447
  const addEffect = callback => createSubs(callback, globalEffects);
1448
+ /**
1449
+ * Adds a global after-render callback which is called each frame.
1450
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addAfterEffect
1451
+ */
1452
+
1405
1453
  const addAfterEffect = callback => createSubs(callback, globalAfterEffects);
1454
+ /**
1455
+ * Adds a global callback which is called when rendering stops.
1456
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addTail
1457
+ */
1458
+
1406
1459
  const addTail = callback => createSubs(callback, globalTailEffects);
1407
1460
 
1408
1461
  function run(effects, timestamp) {
@@ -1411,11 +1464,10 @@ function run(effects, timestamp) {
1411
1464
 
1412
1465
  let subscribers;
1413
1466
  let subscription;
1414
- let delta;
1415
1467
 
1416
1468
  function render$1(timestamp, state, frame) {
1417
1469
  // Run local effects
1418
- delta = state.clock.getDelta(); // In frameloop='never' mode, clock times are updated using the provided timestamp
1470
+ let delta = state.clock.getDelta(); // In frameloop='never' mode, clock times are updated using the provided timestamp
1419
1471
 
1420
1472
  if (state.frameloop === 'never' && typeof timestamp === 'number') {
1421
1473
  delta = timestamp - state.clock.elapsedTime;
@@ -1494,7 +1546,17 @@ function createLoop(roots) {
1494
1546
 
1495
1547
  return {
1496
1548
  loop,
1549
+
1550
+ /**
1551
+ * Invalidates the view, requesting a frame to be rendered. Will globally invalidate unless passed a root's state.
1552
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#invalidate
1553
+ */
1497
1554
  invalidate,
1555
+
1556
+ /**
1557
+ * Advances the frameloop and runs render effects, useful for when manually rendering via `frameloop="never"`.
1558
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#advance
1559
+ */
1498
1560
  advance
1499
1561
  };
1500
1562
  }
@@ -1504,19 +1566,34 @@ function useStore() {
1504
1566
  if (!store) throw `R3F hooks can only be used within the Canvas component!`;
1505
1567
  return store;
1506
1568
  }
1569
+ /**
1570
+ * Accesses R3F's internal state, containing renderer, canvas, scene, etc.
1571
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usethree
1572
+ */
1573
+
1507
1574
  function useThree(selector = state => state, equalityFn) {
1508
1575
  return useStore()(selector, equalityFn);
1509
1576
  }
1577
+ /**
1578
+ * Executes a callback before render in a shared frame loop.
1579
+ * Can order effects with render priority or manually render with a positive priority.
1580
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe
1581
+ */
1582
+
1510
1583
  function useFrame(callback, renderPriority = 0) {
1511
1584
  const store = useStore();
1512
- const subscribe = store.getState().internal.subscribe; // Update ref
1585
+ const subscribe = store.getState().internal.subscribe; // Memoize ref
1513
1586
 
1514
- const ref = React__namespace.useRef(callback);
1515
- React__namespace.useLayoutEffect(() => void (ref.current = callback), [callback]); // Subscribe on mount, unsubscribe on unmount
1587
+ const ref = useMutableCallback(callback); // Subscribe on mount, unsubscribe on unmount
1516
1588
 
1517
- React__namespace.useLayoutEffect(() => subscribe(ref, renderPriority, store), [renderPriority, subscribe, store]);
1589
+ useIsomorphicLayoutEffect(() => subscribe(ref, renderPriority, store), [renderPriority, subscribe, store]);
1518
1590
  return null;
1519
1591
  }
1592
+ /**
1593
+ * Returns a node graph of an object with named nodes & materials.
1594
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usegraph
1595
+ */
1596
+
1520
1597
  function useGraph(object) {
1521
1598
  return React__namespace.useMemo(() => buildGraph(object), [object]);
1522
1599
  }
@@ -1533,12 +1610,14 @@ function loadingFn(extensions, onProgress) {
1533
1610
  }, onProgress, error => reject(`Could not load ${input}: ${error.message}`)))));
1534
1611
  };
1535
1612
  }
1613
+ /**
1614
+ * Synchronously loads and caches assets with a three loader.
1615
+ *
1616
+ * Note: this hook's caller must be wrapped with `React.Suspense`
1617
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useloader
1618
+ */
1619
+
1536
1620
 
1537
- function useMemoizedFn(fn) {
1538
- const fnRef = React__namespace.useRef(fn);
1539
- React__namespace.useLayoutEffect(() => void (fnRef.current = fn), [fn]);
1540
- return (...args) => fnRef.current == null ? void 0 : fnRef.current(...args);
1541
- }
1542
1621
  function useLoader(Proto, input, extensions, onProgress) {
1543
1622
  // Use suspense to load async assets
1544
1623
  const keys = Array.isArray(input) ? input : [input];
@@ -1548,11 +1627,18 @@ function useLoader(Proto, input, extensions, onProgress) {
1548
1627
 
1549
1628
  return Array.isArray(input) ? results : results[0];
1550
1629
  }
1630
+ /**
1631
+ * Preloads an asset into cache as a side-effect.
1632
+ */
1551
1633
 
1552
1634
  useLoader.preload = function (Proto, input, extensions) {
1553
1635
  const keys = Array.isArray(input) ? input : [input];
1554
1636
  return suspendReact.preload(loadingFn(extensions), [Proto, ...keys]);
1555
1637
  };
1638
+ /**
1639
+ * Removes a loaded asset from cache.
1640
+ */
1641
+
1556
1642
 
1557
1643
  useLoader.clear = function (Proto, input) {
1558
1644
  const keys = Array.isArray(input) ? input : [input];
@@ -1799,7 +1885,7 @@ function Provider({
1799
1885
  onCreated,
1800
1886
  rootElement
1801
1887
  }) {
1802
- React__namespace.useLayoutEffect(() => {
1888
+ useIsomorphicLayoutEffect(() => {
1803
1889
  const state = store.getState(); // Flag the canvas active, rendering will now begin
1804
1890
 
1805
1891
  state.set(state => ({
@@ -1868,6 +1954,7 @@ function Portal({
1868
1954
  * {createPortal(...)} */
1869
1955
  const {
1870
1956
  events,
1957
+ size,
1871
1958
  ...rest
1872
1959
  } = state;
1873
1960
  const previousRoot = useStore();
@@ -1879,45 +1966,79 @@ function Portal({
1879
1966
 
1880
1967
  if (injectState) {
1881
1968
  // Only the fields of "state" that do not differ from injectState
1969
+ // Some props should be off-limits
1970
+ // Otherwise filter out the props that are different and let the inject layer take precedence
1882
1971
  Object.keys(state).forEach(key => {
1883
- if ( // Some props should be off-limits
1884
- !['size', 'viewport', 'internal', 'performance'].includes(key) && // Otherwise filter out the props that are different and let the inject layer take precedence
1885
- state[key] !== injectState[key]) delete intersect[key];
1972
+ if (state[key] !== injectState[key] && !['internal', 'performance'].includes(key)) {
1973
+ delete intersect[key];
1974
+ }
1886
1975
  });
1887
1976
  }
1888
1977
 
1889
- return { ...intersect,
1978
+ let viewport = undefined;
1979
+
1980
+ if (injectState && size) {
1981
+ const camera = injectState.camera; // Calculate the override viewport, if present
1982
+
1983
+ viewport = state.viewport.getCurrentViewport(camera, new THREE__namespace.Vector3(), size); // Update the portal camera, if it differs from the previous layer
1984
+
1985
+ if (camera !== state.camera) updateCamera(camera, size);
1986
+ }
1987
+
1988
+ return { // The intersect consists of the previous root state
1989
+ ...intersect,
1990
+ // Portals have their own scene, which forms the root, a raycaster and a pointer
1890
1991
  scene: container,
1891
- previousRoot,
1892
1992
  raycaster,
1993
+ pointer,
1994
+ mouse: pointer,
1995
+ // Their previous root is the layer before it
1996
+ previousRoot,
1997
+ // Events, size and viewport can be overridden by the inject layer
1893
1998
  events: { ...state.events,
1894
1999
  ...(injectState == null ? void 0 : injectState.events),
1895
- pointer,
1896
- mouse: pointer,
1897
2000
  ...events
1898
2001
  },
2002
+ size: { ...state.size,
2003
+ ...size
2004
+ },
2005
+ viewport: { ...state.viewport,
2006
+ ...viewport
2007
+ },
1899
2008
  ...rest
1900
2009
  };
1901
2010
  }, [state]);
1902
- const [useInjectStore] = React__namespace.useState(() => {
1903
- const store = create__default['default']((set, get) => ({ ...inject(previousRoot.getState()),
2011
+ const [usePortalStore] = React__namespace.useState(() => {
2012
+ // Create a mirrored store, based on the previous root with a few overrides ...
2013
+ new THREE__namespace.Vector3();
2014
+ const previousState = previousRoot.getState();
2015
+ const store = create__default['default']((set, get) => ({ ...inject(previousState),
2016
+ // Set and get refer to this root-state
1904
2017
  set,
1905
2018
  get,
2019
+ // Layers are allowed to override events
1906
2020
  setEvents: events => set(state => ({ ...state,
1907
2021
  events: { ...state.events,
1908
2022
  ...events
1909
2023
  }
1910
2024
  }))
1911
2025
  }));
1912
- previousRoot.subscribe(state => useInjectStore.setState(injectState => inject(state, injectState)));
1913
2026
  return store;
1914
2027
  });
1915
2028
  React__namespace.useEffect(() => {
1916
- useInjectStore.setState(injectState => inject(previousRoot.getState(), injectState));
2029
+ // Subscribe to previous root-state and copy changes over to the mirrored portal-state
2030
+ const unsub = previousRoot.subscribe(prev => usePortalStore.setState(state => inject(prev, state)));
2031
+ return () => {
2032
+ unsub();
2033
+ usePortalStore.destroy();
2034
+ };
2035
+ }, []);
2036
+ React__namespace.useEffect(() => {
2037
+ usePortalStore.setState(injectState => inject(previousRoot.getState(), injectState));
1917
2038
  }, [inject]);
1918
2039
  return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, reconciler.createPortal( /*#__PURE__*/React__namespace.createElement(context.Provider, {
1919
- value: useInjectStore
1920
- }, children), useInjectStore, null));
2040
+ value: usePortalStore
2041
+ }, children), usePortalStore, null));
1921
2042
  }
1922
2043
 
1923
2044
  reconciler.injectIntoDevTools({
@@ -1927,6 +2048,8 @@ reconciler.injectIntoDevTools({
1927
2048
  });
1928
2049
  const act = React__namespace.unstable_act;
1929
2050
 
2051
+ exports.Block = Block;
2052
+ exports.ErrorBoundary = ErrorBoundary;
1930
2053
  exports.act = act;
1931
2054
  exports.addAfterEffect = addAfterEffect;
1932
2055
  exports.addEffect = addEffect;
@@ -1950,7 +2073,8 @@ exports.threeTypes = threeTypes;
1950
2073
  exports.unmountComponentAtNode = unmountComponentAtNode;
1951
2074
  exports.useFrame = useFrame;
1952
2075
  exports.useGraph = useGraph;
2076
+ exports.useIsomorphicLayoutEffect = useIsomorphicLayoutEffect;
1953
2077
  exports.useLoader = useLoader;
1954
- exports.useMemoizedFn = useMemoizedFn;
2078
+ exports.useMutableCallback = useMutableCallback;
1955
2079
  exports.useStore = useStore;
1956
2080
  exports.useThree = useThree;
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require('./index-75d39ab1.cjs.dev.js');
5
+ var index = require('./index-018d2d45.cjs.dev.js');
6
6
  var _extends = require('@babel/runtime/helpers/extends');
7
7
  var React = require('react');
8
8
  var THREE = require('three');
@@ -53,6 +53,8 @@ const DOM_EVENTS = {
53
53
  onPointerCancel: ['pointercancel', true],
54
54
  onLostPointerCapture: ['lostpointercapture', true]
55
55
  };
56
+ /** Default R3F event manager for web */
57
+
56
58
  function createPointerEvents(store) {
57
59
  const {
58
60
  handlePointer
@@ -76,13 +78,15 @@ function createPointerEvents(store) {
76
78
  var _events$handlers;
77
79
 
78
80
  const {
79
- setEvents,
81
+ set,
80
82
  events
81
83
  } = store.getState();
82
84
  events.disconnect == null ? void 0 : events.disconnect();
83
- setEvents({
84
- connected: target
85
- });
85
+ set(state => ({
86
+ events: { ...state.events,
87
+ connected: target
88
+ }
89
+ }));
86
90
  Object.entries((_events$handlers = events == null ? void 0 : events.handlers) != null ? _events$handlers : []).forEach(([name, event]) => {
87
91
  const [eventName, passive] = DOM_EVENTS[name];
88
92
  target.addEventListener(eventName, event, {
@@ -92,7 +96,7 @@ function createPointerEvents(store) {
92
96
  },
93
97
  disconnect: () => {
94
98
  const {
95
- setEvents,
99
+ set,
96
100
  events
97
101
  } = store.getState();
98
102
 
@@ -105,53 +109,28 @@ function createPointerEvents(store) {
105
109
  events.connected.removeEventListener(eventName, event);
106
110
  }
107
111
  });
108
- setEvents({
109
- connected: undefined
110
- });
112
+ set(state => ({
113
+ events: { ...state.events,
114
+ connected: undefined
115
+ }
116
+ }));
111
117
  }
112
118
  }
113
119
  };
114
120
  }
115
121
 
116
122
  const CANVAS_PROPS = ['gl', 'events', 'shadows', 'linear', 'flat', 'legacy', 'orthographic', 'frameloop', 'dpr', 'performance', 'raycaster', 'camera', 'onPointerMissed', 'onCreated'];
117
-
118
- function Block({
119
- set
120
- }) {
121
- React__namespace.useLayoutEffect(() => {
122
- set(new Promise(() => null));
123
- return () => set(false);
124
- }, [set]);
125
- return null;
126
- }
127
-
128
- class ErrorBoundary extends React__namespace.Component {
129
- constructor(...args) {
130
- super(...args);
131
- this.state = {
132
- error: false
133
- };
134
- }
135
-
136
- componentDidCatch(error) {
137
- this.props.set(error);
138
- }
139
-
140
- render() {
141
- return this.state.error ? null : this.props.children;
142
- }
143
-
144
- }
145
-
146
- ErrorBoundary.getDerivedStateFromError = () => ({
147
- error: true
148
- });
123
+ /**
124
+ * A DOM canvas which accepts threejs elements as children.
125
+ * @see https://docs.pmnd.rs/react-three-fiber/api/canvas
126
+ */
149
127
 
150
128
  const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
151
129
  children,
152
130
  fallback,
153
131
  resize,
154
132
  style,
133
+ onPointerMissed,
155
134
  events = createPointerEvents,
156
135
  ...props
157
136
  }, forwardedRef) {
@@ -159,7 +138,6 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
159
138
  // This will include the entire THREE namespace by default, users can extend
160
139
  // their own elements by using the createRoot API instead
161
140
  React__namespace.useMemo(() => index.extend(THREE__namespace), []);
162
- const onPointerMissed = index.useMemoizedFn(props.onPointerMissed);
163
141
  const [containerRef, {
164
142
  width,
165
143
  height
@@ -171,15 +149,12 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
171
149
  },
172
150
  ...resize
173
151
  });
174
- const meshRef = React__namespace.useRef(null);
175
152
  const canvasRef = React__namespace.useRef(null);
153
+ const meshRef = React__namespace.useRef(null);
176
154
  const [canvas, setCanvas] = React__namespace.useState(null);
177
- const canvasProps = index.pick({ ...props,
178
- onPointerMissed
179
- }, CANVAS_PROPS);
180
- const divProps = index.omit({ ...props,
181
- onPointerMissed
182
- }, CANVAS_PROPS);
155
+ const handlePointerMissed = index.useMutableCallback(onPointerMissed);
156
+ const canvasProps = index.pick(props, CANVAS_PROPS);
157
+ const divProps = index.omit(props, CANVAS_PROPS);
183
158
  const [block, setBlock] = React__namespace.useState(false);
184
159
  const [error, setError] = React__namespace.useState(false); // Suspend this component if block is a promise (2nd run)
185
160
 
@@ -191,6 +166,8 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
191
166
  if (width > 0 && height > 0 && canvas) {
192
167
  if (!root.current) root.current = index.createRoot(canvas);
193
168
  root.current.configure({ ...canvasProps,
169
+ // Pass mutable reference to onPointerMissed so it's free to update
170
+ onPointerMissed: (...args) => handlePointerMissed.current == null ? void 0 : handlePointerMissed.current(...args),
194
171
  onCreated: state => {
195
172
  state.events.connect == null ? void 0 : state.events.connect(meshRef.current);
196
173
  canvasProps.onCreated == null ? void 0 : canvasProps.onCreated(state);
@@ -201,20 +178,20 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
201
178
  },
202
179
  events
203
180
  });
204
- root.current.render( /*#__PURE__*/React__namespace.createElement(ErrorBoundary, {
181
+ root.current.render( /*#__PURE__*/React__namespace.createElement(index.ErrorBoundary, {
205
182
  set: setError
206
183
  }, /*#__PURE__*/React__namespace.createElement(React__namespace.Suspense, {
207
- fallback: /*#__PURE__*/React__namespace.createElement(Block, {
184
+ fallback: /*#__PURE__*/React__namespace.createElement(index.Block, {
208
185
  set: setBlock
209
186
  })
210
187
  }, children)));
211
188
  }
212
189
 
213
- React__namespace.useLayoutEffect(() => {
190
+ index.useIsomorphicLayoutEffect(() => {
214
191
  setCanvas(canvasRef.current);
215
192
  }, []);
216
193
  React__namespace.useEffect(() => {
217
- return () => index.unmountComponentAtNode(canvas);
194
+ if (canvas) return () => index.unmountComponentAtNode(canvas);
218
195
  }, [canvas]);
219
196
  return /*#__PURE__*/React__namespace.createElement("div", _extends({
220
197
  ref: mergeRefs__default['default']([meshRef, containerRef]),
@@ -254,7 +231,6 @@ exports.unmountComponentAtNode = index.unmountComponentAtNode;
254
231
  exports.useFrame = index.useFrame;
255
232
  exports.useGraph = index.useGraph;
256
233
  exports.useLoader = index.useLoader;
257
- exports.useMemoizedFn = index.useMemoizedFn;
258
234
  exports.useStore = index.useStore;
259
235
  exports.useThree = index.useThree;
260
236
  exports.Canvas = Canvas;