Skip to content

Commit be84af8

Browse files
author
Philipp Molitor
committed
remove double reference and migrate to useRef hook
1 parent 7a0d5a1 commit be84af8

File tree

1 file changed

+13
-26
lines changed

1 file changed

+13
-26
lines changed

src/components/UnityRenderer.ts renamed to src/components/UnityRenderer.tsx

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createElement, HTMLAttributes, useEffect, useState, VFC } from 'react';
1+
import { HTMLAttributes, useEffect, useRef, useState, VFC } from 'react';
22

33
import { useScript } from '../hooks/useScript';
44
import { UnityContext } from '../lib/context';
@@ -20,7 +20,7 @@ export type UnityRendererProps = Omit<
2020
* @param {UnityRendererProps} props Configurtion context, Unity-specific
2121
* callback handlers and default React props for a `HTMLCanvasElement`.
2222
* Note that `ref` is not available due to internal use.
23-
* @returns {(JSX.Element | null)} A `JSX.Element` containing the renderer,
23+
* @returns {JSX.Element | null} A `JSX.Element` containing the renderer,
2424
* or `null` if not initialized yet.
2525
*/
2626
export const UnityRenderer: VFC<UnityRendererProps> = ({
@@ -33,10 +33,9 @@ export const UnityRenderer: VFC<UnityRendererProps> = ({
3333
const [ctx, setCtx] = useState<UnityContext | undefined>(context);
3434
const [loaderState, setLoaderSource] = useScript(ctx?.getConfig().loaderUrl);
3535

36-
// We cannot actually render the `HTMLCanvasElement`, so we need the `ref`
37-
// for Unity and a `JSX.Element` for React rendering.
38-
const [canvas, setCanvas] = useState<JSX.Element>();
39-
const [renderer, setRenderer] = useState<HTMLCanvasElement>();
36+
// Reference to the actual <canvas> element, which has to be passed to
37+
// the native `createUnityInstance()` method.
38+
const canvas = useRef<HTMLCanvasElement>(null);
4039

4140
// This is the last state the game was in, either ready or not ready.
4241
// It is used to trigger `onUnityReadyStateChange` reliably.
@@ -104,18 +103,18 @@ export const UnityRenderer: VFC<UnityRendererProps> = ({
104103
* Unity instance.
105104
*/
106105
async function mount(): Promise<void> {
107-
// if no context, renderer or loader is availiable, or the game is already loaded
108-
if (!ctx || !renderer || loaderState !== 'active' || lastReadyState) {
106+
// if no context or loader is available, or the game is already loaded
107+
if (!ctx || !canvas.current || loaderState !== 'active' || lastReadyState) {
109108
throw new Error(
110-
'cannot mount unity instance without a context, loader or renderer'
109+
'cannot mount unity instance without a context or loader'
111110
);
112111
}
113112

114113
// get the current loader configuration from the UnityContext
115114
const c = ctx.getConfig();
116115

117116
const instance = await window.createUnityInstance(
118-
renderer,
117+
canvas.current,
119118
{
120119
dataUrl: c.dataUrl,
121120
frameworkUrl: c.frameworkUrl,
@@ -171,21 +170,9 @@ export const UnityRenderer: VFC<UnityRendererProps> = ({
171170
}
172171
}, [loaderState]);
173172

174-
// on mount
175-
useEffect(() => {
176-
// create the renderer and let the ref callback set its handle
177-
setCanvas(
178-
createElement('canvas', {
179-
ref: (r: HTMLCanvasElement) => setRenderer(r),
180-
...canvasProps,
181-
})
182-
);
183-
184-
// on unmount
185-
return () => {
186-
unmount();
187-
};
188-
}, []);
173+
// on unmount
174+
useEffect(() => () => unmount(), []);
189175

190-
return canvas || null;
176+
// eslint-disable-next-line react/jsx-props-no-spreading
177+
return <canvas {...canvasProps} ref={canvas} />;
191178
};

0 commit comments

Comments
 (0)