@croquet/react
Version:
React bindings for Croquet
63 lines (62 loc) • 2.35 kB
JavaScript
import { useEffect, useState, createElement } from 'react';
import { Session } from '@croquet/croquet';
import { CroquetReactView } from '../CroquetReactView';
import { CroquetContext } from './CroquetContext';
/** Main wrapper component that starts and manages a croquet session, enabling child elements to use the
* {@link usePublish}, {@link useSubscribe}, {@link useObservable}, {@link useViewId} and {@link useModelRoot} hooks.
*
* Takes the same parameters as {@link Session.join} except that it doesn't need a root View class,
* since croquet-react provides a suitable View class behind the scenes.
*
* ```
* function MyApp() {
* return (
* <InCroquetSession
* apiKey='1_123abc',
* appId='com.example.myapp'
* name='mySession'
* password='secret'
* model={MyRootModel}
* ...
* >
* // child elements that use hooks go here...
* </InCroquetSession>
* )
* }
* ```
*/
export function InCroquetSession(params) {
const children = params.children;
const [croquetSession, setCroquetSession] = useState(undefined);
const [joining, setJoining] = useState(false);
useEffect(() => {
console.log('InCroquetSession effect');
setJoining((old) => {
if (old)
return old;
const sessionParams = Object.assign(Object.assign({}, params), { view: (CroquetReactView) });
delete sessionParams.children;
console.log('calling Session.join()');
Session.join(Object.assign({}, sessionParams)).then(setCroquetSession);
return true;
});
return () => {
// we don't have to reset the session object or such.
// The same Croquet session should be kept during the life time of the page
// unless it is explicitly destroyed.
// console.log('unmount')
};
}, [joining, params]);
if (croquetSession) {
const contextValue = {
session: croquetSession,
view: croquetSession.view,
model: croquetSession.view.model,
setSession: () => { },
leaveSession: () => { },
sessionParams: params,
};
return createElement(CroquetContext.Provider, { value: contextValue }, children);
}
return null;
}