@react-three/fiber 8.0.6 → 8.0.9

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.
@@ -10,6 +10,47 @@ var threeTypes = /*#__PURE__*/Object.freeze({
10
10
  __proto__: null
11
11
  });
12
12
 
13
+ // React currently throws a warning when using useLayoutEffect on the server.
14
+ // To get around it, we can conditionally useEffect on the server (no-op) and
15
+ // useLayoutEffect on the client.
16
+ const isSSR = typeof window === 'undefined' || !window.navigator || /ServerSideRendering|^Deno\//.test(window.navigator.userAgent);
17
+ const useIsomorphicLayoutEffect = isSSR ? React.useEffect : React.useLayoutEffect;
18
+ function useMutableCallback(fn) {
19
+ const ref = React.useRef(fn);
20
+ useIsomorphicLayoutEffect(() => void (ref.current = fn), [fn]);
21
+ return ref;
22
+ }
23
+ function Block({
24
+ set
25
+ }) {
26
+ useIsomorphicLayoutEffect(() => {
27
+ set(new Promise(() => null));
28
+ return () => set(false);
29
+ }, [set]);
30
+ return null;
31
+ }
32
+ class ErrorBoundary extends React.Component {
33
+ constructor(...args) {
34
+ super(...args);
35
+ this.state = {
36
+ error: false
37
+ };
38
+ }
39
+
40
+ componentDidCatch(error) {
41
+ this.props.set(error);
42
+ }
43
+
44
+ render() {
45
+ return this.state.error ? null : this.props.children;
46
+ }
47
+
48
+ }
49
+
50
+ ErrorBoundary.getDerivedStateFromError = () => ({
51
+ error: true
52
+ });
53
+
13
54
  const DEFAULT = '__default';
14
55
  const isDiffSet = def => def && !!def.memoized && !!def.changes;
15
56
  function calculateDpr(dpr) {
@@ -1367,8 +1408,23 @@ let i;
1367
1408
  let globalEffects = [];
1368
1409
  let globalAfterEffects = [];
1369
1410
  let globalTailEffects = [];
1411
+ /**
1412
+ * Adds a global render callback which is called each frame.
1413
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addEffect
1414
+ */
1415
+
1370
1416
  const addEffect = callback => createSubs(callback, globalEffects);
1417
+ /**
1418
+ * Adds a global after-render callback which is called each frame.
1419
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addAfterEffect
1420
+ */
1421
+
1371
1422
  const addAfterEffect = callback => createSubs(callback, globalAfterEffects);
1423
+ /**
1424
+ * Adds a global callback which is called when rendering stops.
1425
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addTail
1426
+ */
1427
+
1372
1428
  const addTail = callback => createSubs(callback, globalTailEffects);
1373
1429
 
1374
1430
  function run(effects, timestamp) {
@@ -1459,7 +1515,17 @@ function createLoop(roots) {
1459
1515
 
1460
1516
  return {
1461
1517
  loop,
1518
+
1519
+ /**
1520
+ * Invalidates the view, requesting a frame to be rendered. Will globally invalidate unless passed a root's state.
1521
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#invalidate
1522
+ */
1462
1523
  invalidate,
1524
+
1525
+ /**
1526
+ * Advances the frameloop and runs render effects, useful for when manually rendering via `frameloop="never"`.
1527
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#advance
1528
+ */
1463
1529
  advance
1464
1530
  };
1465
1531
  }
@@ -1469,19 +1535,34 @@ function useStore() {
1469
1535
  if (!store) throw `R3F hooks can only be used within the Canvas component!`;
1470
1536
  return store;
1471
1537
  }
1538
+ /**
1539
+ * Accesses R3F's internal state, containing renderer, canvas, scene, etc.
1540
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usethree
1541
+ */
1542
+
1472
1543
  function useThree(selector = state => state, equalityFn) {
1473
1544
  return useStore()(selector, equalityFn);
1474
1545
  }
1546
+ /**
1547
+ * Executes a callback before render in a shared frame loop.
1548
+ * Can order effects with render priority or manually render with a positive priority.
1549
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe
1550
+ */
1551
+
1475
1552
  function useFrame(callback, renderPriority = 0) {
1476
1553
  const store = useStore();
1477
- const subscribe = store.getState().internal.subscribe; // Update ref
1554
+ const subscribe = store.getState().internal.subscribe; // Memoize ref
1478
1555
 
1479
- const ref = React.useRef(callback);
1480
- React.useLayoutEffect(() => void (ref.current = callback), [callback]); // Subscribe on mount, unsubscribe on unmount
1556
+ const ref = useMutableCallback(callback); // Subscribe on mount, unsubscribe on unmount
1481
1557
 
1482
- React.useLayoutEffect(() => subscribe(ref, renderPriority, store), [renderPriority, subscribe, store]);
1558
+ useIsomorphicLayoutEffect(() => subscribe(ref, renderPriority, store), [renderPriority, subscribe, store]);
1483
1559
  return null;
1484
1560
  }
1561
+ /**
1562
+ * Returns a node graph of an object with named nodes & materials.
1563
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usegraph
1564
+ */
1565
+
1485
1566
  function useGraph(object) {
1486
1567
  return React.useMemo(() => buildGraph(object), [object]);
1487
1568
  }
@@ -1498,12 +1579,14 @@ function loadingFn(extensions, onProgress) {
1498
1579
  }, onProgress, error => reject(`Could not load ${input}: ${error.message}`)))));
1499
1580
  };
1500
1581
  }
1582
+ /**
1583
+ * Synchronously loads and caches assets with a three loader.
1584
+ *
1585
+ * Note: this hook's caller must be wrapped with `React.Suspense`
1586
+ * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useloader
1587
+ */
1588
+
1501
1589
 
1502
- function useMemoizedFn(fn) {
1503
- const fnRef = React.useRef(fn);
1504
- React.useLayoutEffect(() => void (fnRef.current = fn), [fn]);
1505
- return (...args) => fnRef.current == null ? void 0 : fnRef.current(...args);
1506
- }
1507
1590
  function useLoader(Proto, input, extensions, onProgress) {
1508
1591
  // Use suspense to load async assets
1509
1592
  const keys = Array.isArray(input) ? input : [input];
@@ -1513,11 +1596,18 @@ function useLoader(Proto, input, extensions, onProgress) {
1513
1596
 
1514
1597
  return Array.isArray(input) ? results : results[0];
1515
1598
  }
1599
+ /**
1600
+ * Preloads an asset into cache as a side-effect.
1601
+ */
1516
1602
 
1517
1603
  useLoader.preload = function (Proto, input, extensions) {
1518
1604
  const keys = Array.isArray(input) ? input : [input];
1519
1605
  return preload(loadingFn(extensions), [Proto, ...keys]);
1520
1606
  };
1607
+ /**
1608
+ * Removes a loaded asset from cache.
1609
+ */
1610
+
1521
1611
 
1522
1612
  useLoader.clear = function (Proto, input) {
1523
1613
  const keys = Array.isArray(input) ? input : [input];
@@ -1764,7 +1854,7 @@ function Provider({
1764
1854
  onCreated,
1765
1855
  rootElement
1766
1856
  }) {
1767
- React.useLayoutEffect(() => {
1857
+ useIsomorphicLayoutEffect(() => {
1768
1858
  const state = store.getState(); // Flag the canvas active, rendering will now begin
1769
1859
 
1770
1860
  state.set(state => ({
@@ -1892,4 +1982,4 @@ reconciler.injectIntoDevTools({
1892
1982
  });
1893
1983
  const act = React.unstable_act;
1894
1984
 
1895
- export { useLoader as A, createRoot as a, unmountComponentAtNode as b, createEvents as c, context as d, extend as e, createPortal as f, reconciler as g, applyProps as h, dispose as i, invalidate as j, advance as k, addEffect as l, addAfterEffect as m, addTail as n, omit as o, pick as p, getRootState as q, render as r, act as s, threeTypes as t, useMemoizedFn as u, roots as v, useStore as w, useThree as x, useFrame as y, useGraph as z };
1985
+ export { useGraph as A, Block as B, useLoader as C, ErrorBoundary as E, createRoot as a, useIsomorphicLayoutEffect as b, createEvents as c, unmountComponentAtNode as d, extend as e, context as f, createPortal as g, reconciler as h, applyProps as i, dispose as j, invalidate as k, advance as l, addEffect as m, addAfterEffect as n, omit as o, pick as p, addTail as q, render as r, getRootState as s, threeTypes as t, useMutableCallback as u, act as v, roots as w, useStore as x, useThree as y, useFrame as z };
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require('./index-0076cbd6.cjs.dev.js');
5
+ var index = require('./index-49237346.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
@@ -118,44 +120,17 @@ function createPointerEvents(store) {
118
120
  }
119
121
 
120
122
  const CANVAS_PROPS = ['gl', 'events', 'shadows', 'linear', 'flat', 'legacy', 'orthographic', 'frameloop', 'dpr', 'performance', 'raycaster', 'camera', 'onPointerMissed', 'onCreated'];
121
-
122
- function Block({
123
- set
124
- }) {
125
- React__namespace.useLayoutEffect(() => {
126
- set(new Promise(() => null));
127
- return () => set(false);
128
- }, [set]);
129
- return null;
130
- }
131
-
132
- class ErrorBoundary extends React__namespace.Component {
133
- constructor(...args) {
134
- super(...args);
135
- this.state = {
136
- error: false
137
- };
138
- }
139
-
140
- componentDidCatch(error) {
141
- this.props.set(error);
142
- }
143
-
144
- render() {
145
- return this.state.error ? null : this.props.children;
146
- }
147
-
148
- }
149
-
150
- ErrorBoundary.getDerivedStateFromError = () => ({
151
- error: true
152
- });
123
+ /**
124
+ * A DOM canvas which accepts threejs elements as children.
125
+ * @see https://docs.pmnd.rs/react-three-fiber/api/canvas
126
+ */
153
127
 
154
128
  const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
155
129
  children,
156
130
  fallback,
157
131
  resize,
158
132
  style,
133
+ onPointerMissed,
159
134
  events = createPointerEvents,
160
135
  ...props
161
136
  }, forwardedRef) {
@@ -163,7 +138,6 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
163
138
  // This will include the entire THREE namespace by default, users can extend
164
139
  // their own elements by using the createRoot API instead
165
140
  React__namespace.useMemo(() => index.extend(THREE__namespace), []);
166
- const onPointerMissed = index.useMemoizedFn(props.onPointerMissed);
167
141
  const [containerRef, {
168
142
  width,
169
143
  height
@@ -178,12 +152,9 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
178
152
  const meshRef = React__namespace.useRef(null);
179
153
  const canvasRef = React__namespace.useRef(null);
180
154
  const [canvas, setCanvas] = React__namespace.useState(null);
181
- const canvasProps = index.pick({ ...props,
182
- onPointerMissed
183
- }, CANVAS_PROPS);
184
- const divProps = index.omit({ ...props,
185
- onPointerMissed
186
- }, CANVAS_PROPS);
155
+ const handlePointerMissed = index.useMutableCallback(onPointerMissed);
156
+ const canvasProps = index.pick(props, CANVAS_PROPS);
157
+ const divProps = index.omit(props, CANVAS_PROPS);
187
158
  const [block, setBlock] = React__namespace.useState(false);
188
159
  const [error, setError] = React__namespace.useState(false); // Suspend this component if block is a promise (2nd run)
189
160
 
@@ -195,6 +166,8 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
195
166
  if (width > 0 && height > 0 && canvas) {
196
167
  if (!root.current) root.current = index.createRoot(canvas);
197
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),
198
171
  onCreated: state => {
199
172
  state.events.connect == null ? void 0 : state.events.connect(meshRef.current);
200
173
  canvasProps.onCreated == null ? void 0 : canvasProps.onCreated(state);
@@ -205,21 +178,21 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
205
178
  },
206
179
  events
207
180
  });
208
- root.current.render( /*#__PURE__*/React__namespace.createElement(ErrorBoundary, {
181
+ root.current.render( /*#__PURE__*/React__namespace.createElement(index.ErrorBoundary, {
209
182
  set: setError
210
183
  }, /*#__PURE__*/React__namespace.createElement(React__namespace.Suspense, {
211
- fallback: /*#__PURE__*/React__namespace.createElement(Block, {
184
+ fallback: /*#__PURE__*/React__namespace.createElement(index.Block, {
212
185
  set: setBlock
213
186
  })
214
187
  }, children)));
215
188
  }
216
189
 
217
- React__namespace.useLayoutEffect(() => {
190
+ index.useIsomorphicLayoutEffect(() => {
218
191
  setCanvas(canvasRef.current);
219
192
  }, []);
220
193
  React__namespace.useEffect(() => {
221
194
  return () => index.unmountComponentAtNode(canvas);
222
- }, [canvas]);
195
+ }, []);
223
196
  return /*#__PURE__*/React__namespace.createElement("div", _extends({
224
197
  ref: mergeRefs__default['default']([meshRef, containerRef]),
225
198
  style: {
@@ -258,7 +231,6 @@ exports.unmountComponentAtNode = index.unmountComponentAtNode;
258
231
  exports.useFrame = index.useFrame;
259
232
  exports.useGraph = index.useGraph;
260
233
  exports.useLoader = index.useLoader;
261
- exports.useMemoizedFn = index.useMemoizedFn;
262
234
  exports.useStore = index.useStore;
263
235
  exports.useThree = index.useThree;
264
236
  exports.Canvas = Canvas;
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require('./index-0e758026.cjs.prod.js');
5
+ var index = require('./index-4dae9cc6.cjs.prod.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
@@ -118,44 +120,17 @@ function createPointerEvents(store) {
118
120
  }
119
121
 
120
122
  const CANVAS_PROPS = ['gl', 'events', 'shadows', 'linear', 'flat', 'legacy', 'orthographic', 'frameloop', 'dpr', 'performance', 'raycaster', 'camera', 'onPointerMissed', 'onCreated'];
121
-
122
- function Block({
123
- set
124
- }) {
125
- React__namespace.useLayoutEffect(() => {
126
- set(new Promise(() => null));
127
- return () => set(false);
128
- }, [set]);
129
- return null;
130
- }
131
-
132
- class ErrorBoundary extends React__namespace.Component {
133
- constructor(...args) {
134
- super(...args);
135
- this.state = {
136
- error: false
137
- };
138
- }
139
-
140
- componentDidCatch(error) {
141
- this.props.set(error);
142
- }
143
-
144
- render() {
145
- return this.state.error ? null : this.props.children;
146
- }
147
-
148
- }
149
-
150
- ErrorBoundary.getDerivedStateFromError = () => ({
151
- error: true
152
- });
123
+ /**
124
+ * A DOM canvas which accepts threejs elements as children.
125
+ * @see https://docs.pmnd.rs/react-three-fiber/api/canvas
126
+ */
153
127
 
154
128
  const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
155
129
  children,
156
130
  fallback,
157
131
  resize,
158
132
  style,
133
+ onPointerMissed,
159
134
  events = createPointerEvents,
160
135
  ...props
161
136
  }, forwardedRef) {
@@ -163,7 +138,6 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
163
138
  // This will include the entire THREE namespace by default, users can extend
164
139
  // their own elements by using the createRoot API instead
165
140
  React__namespace.useMemo(() => index.extend(THREE__namespace), []);
166
- const onPointerMissed = index.useMemoizedFn(props.onPointerMissed);
167
141
  const [containerRef, {
168
142
  width,
169
143
  height
@@ -178,12 +152,9 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
178
152
  const meshRef = React__namespace.useRef(null);
179
153
  const canvasRef = React__namespace.useRef(null);
180
154
  const [canvas, setCanvas] = React__namespace.useState(null);
181
- const canvasProps = index.pick({ ...props,
182
- onPointerMissed
183
- }, CANVAS_PROPS);
184
- const divProps = index.omit({ ...props,
185
- onPointerMissed
186
- }, CANVAS_PROPS);
155
+ const handlePointerMissed = index.useMutableCallback(onPointerMissed);
156
+ const canvasProps = index.pick(props, CANVAS_PROPS);
157
+ const divProps = index.omit(props, CANVAS_PROPS);
187
158
  const [block, setBlock] = React__namespace.useState(false);
188
159
  const [error, setError] = React__namespace.useState(false); // Suspend this component if block is a promise (2nd run)
189
160
 
@@ -195,6 +166,8 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
195
166
  if (width > 0 && height > 0 && canvas) {
196
167
  if (!root.current) root.current = index.createRoot(canvas);
197
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),
198
171
  onCreated: state => {
199
172
  state.events.connect == null ? void 0 : state.events.connect(meshRef.current);
200
173
  canvasProps.onCreated == null ? void 0 : canvasProps.onCreated(state);
@@ -205,21 +178,21 @@ const Canvas = /*#__PURE__*/React__namespace.forwardRef(function Canvas({
205
178
  },
206
179
  events
207
180
  });
208
- root.current.render( /*#__PURE__*/React__namespace.createElement(ErrorBoundary, {
181
+ root.current.render( /*#__PURE__*/React__namespace.createElement(index.ErrorBoundary, {
209
182
  set: setError
210
183
  }, /*#__PURE__*/React__namespace.createElement(React__namespace.Suspense, {
211
- fallback: /*#__PURE__*/React__namespace.createElement(Block, {
184
+ fallback: /*#__PURE__*/React__namespace.createElement(index.Block, {
212
185
  set: setBlock
213
186
  })
214
187
  }, children)));
215
188
  }
216
189
 
217
- React__namespace.useLayoutEffect(() => {
190
+ index.useIsomorphicLayoutEffect(() => {
218
191
  setCanvas(canvasRef.current);
219
192
  }, []);
220
193
  React__namespace.useEffect(() => {
221
194
  return () => index.unmountComponentAtNode(canvas);
222
- }, [canvas]);
195
+ }, []);
223
196
  return /*#__PURE__*/React__namespace.createElement("div", _extends({
224
197
  ref: mergeRefs__default['default']([meshRef, containerRef]),
225
198
  style: {
@@ -258,7 +231,6 @@ exports.unmountComponentAtNode = index.unmountComponentAtNode;
258
231
  exports.useFrame = index.useFrame;
259
232
  exports.useGraph = index.useGraph;
260
233
  exports.useLoader = index.useLoader;
261
- exports.useMemoizedFn = index.useMemoizedFn;
262
234
  exports.useStore = index.useStore;
263
235
  exports.useThree = index.useThree;
264
236
  exports.Canvas = Canvas;
@@ -1,5 +1,5 @@
1
- import { c as createEvents, e as extend, u as useMemoizedFn, p as pick, o as omit, a as createRoot, b as unmountComponentAtNode } from './index-91900b41.esm.js';
2
- export { t as ReactThreeFiber, v as _roots, s as act, m as addAfterEffect, l as addEffect, n as addTail, k as advance, h as applyProps, d as context, f as createPortal, a as createRoot, i as dispose, e as extend, q as getRootState, j as invalidate, g as reconciler, r as render, b as unmountComponentAtNode, y as useFrame, z as useGraph, A as useLoader, u as useMemoizedFn, w as useStore, x as useThree } from './index-91900b41.esm.js';
1
+ import { c as createEvents, e as extend, u as useMutableCallback, p as pick, o as omit, a as createRoot, E as ErrorBoundary, B as Block, b as useIsomorphicLayoutEffect, d as unmountComponentAtNode } from './index-4e14a95b.esm.js';
2
+ export { t as ReactThreeFiber, w as _roots, v as act, n as addAfterEffect, m as addEffect, q as addTail, l as advance, i as applyProps, f as context, g as createPortal, a as createRoot, j as dispose, e as extend, s as getRootState, k as invalidate, h as reconciler, r as render, d as unmountComponentAtNode, z as useFrame, A as useGraph, C as useLoader, x as useStore, y as useThree } from './index-4e14a95b.esm.js';
3
3
  import _extends from '@babel/runtime/helpers/esm/extends';
4
4
  import * as React from 'react';
5
5
  import * as THREE from 'three';
@@ -23,6 +23,8 @@ const DOM_EVENTS = {
23
23
  onPointerCancel: ['pointercancel', true],
24
24
  onLostPointerCapture: ['lostpointercapture', true]
25
25
  };
26
+ /** Default R3F event manager for web */
27
+
26
28
  function createPointerEvents(store) {
27
29
  const {
28
30
  handlePointer
@@ -88,44 +90,17 @@ function createPointerEvents(store) {
88
90
  }
89
91
 
90
92
  const CANVAS_PROPS = ['gl', 'events', 'shadows', 'linear', 'flat', 'legacy', 'orthographic', 'frameloop', 'dpr', 'performance', 'raycaster', 'camera', 'onPointerMissed', 'onCreated'];
91
-
92
- function Block({
93
- set
94
- }) {
95
- React.useLayoutEffect(() => {
96
- set(new Promise(() => null));
97
- return () => set(false);
98
- }, [set]);
99
- return null;
100
- }
101
-
102
- class ErrorBoundary extends React.Component {
103
- constructor(...args) {
104
- super(...args);
105
- this.state = {
106
- error: false
107
- };
108
- }
109
-
110
- componentDidCatch(error) {
111
- this.props.set(error);
112
- }
113
-
114
- render() {
115
- return this.state.error ? null : this.props.children;
116
- }
117
-
118
- }
119
-
120
- ErrorBoundary.getDerivedStateFromError = () => ({
121
- error: true
122
- });
93
+ /**
94
+ * A DOM canvas which accepts threejs elements as children.
95
+ * @see https://docs.pmnd.rs/react-three-fiber/api/canvas
96
+ */
123
97
 
124
98
  const Canvas = /*#__PURE__*/React.forwardRef(function Canvas({
125
99
  children,
126
100
  fallback,
127
101
  resize,
128
102
  style,
103
+ onPointerMissed,
129
104
  events = createPointerEvents,
130
105
  ...props
131
106
  }, forwardedRef) {
@@ -133,7 +108,6 @@ const Canvas = /*#__PURE__*/React.forwardRef(function Canvas({
133
108
  // This will include the entire THREE namespace by default, users can extend
134
109
  // their own elements by using the createRoot API instead
135
110
  React.useMemo(() => extend(THREE), []);
136
- const onPointerMissed = useMemoizedFn(props.onPointerMissed);
137
111
  const [containerRef, {
138
112
  width,
139
113
  height
@@ -148,12 +122,9 @@ const Canvas = /*#__PURE__*/React.forwardRef(function Canvas({
148
122
  const meshRef = React.useRef(null);
149
123
  const canvasRef = React.useRef(null);
150
124
  const [canvas, setCanvas] = React.useState(null);
151
- const canvasProps = pick({ ...props,
152
- onPointerMissed
153
- }, CANVAS_PROPS);
154
- const divProps = omit({ ...props,
155
- onPointerMissed
156
- }, CANVAS_PROPS);
125
+ const handlePointerMissed = useMutableCallback(onPointerMissed);
126
+ const canvasProps = pick(props, CANVAS_PROPS);
127
+ const divProps = omit(props, CANVAS_PROPS);
157
128
  const [block, setBlock] = React.useState(false);
158
129
  const [error, setError] = React.useState(false); // Suspend this component if block is a promise (2nd run)
159
130
 
@@ -165,6 +136,8 @@ const Canvas = /*#__PURE__*/React.forwardRef(function Canvas({
165
136
  if (width > 0 && height > 0 && canvas) {
166
137
  if (!root.current) root.current = createRoot(canvas);
167
138
  root.current.configure({ ...canvasProps,
139
+ // Pass mutable reference to onPointerMissed so it's free to update
140
+ onPointerMissed: (...args) => handlePointerMissed.current == null ? void 0 : handlePointerMissed.current(...args),
168
141
  onCreated: state => {
169
142
  state.events.connect == null ? void 0 : state.events.connect(meshRef.current);
170
143
  canvasProps.onCreated == null ? void 0 : canvasProps.onCreated(state);
@@ -184,12 +157,12 @@ const Canvas = /*#__PURE__*/React.forwardRef(function Canvas({
184
157
  }, children)));
185
158
  }
186
159
 
187
- React.useLayoutEffect(() => {
160
+ useIsomorphicLayoutEffect(() => {
188
161
  setCanvas(canvasRef.current);
189
162
  }, []);
190
163
  React.useEffect(() => {
191
164
  return () => unmountComponentAtNode(canvas);
192
- }, [canvas]);
165
+ }, []);
193
166
  return /*#__PURE__*/React.createElement("div", _extends({
194
167
  ref: mergeRefs([meshRef, containerRef]),
195
168
  style: {