UNPKG

@croquet/react

Version:

React bindings for Croquet

63 lines (62 loc) 2.35 kB
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; }