UNPKG

@multisynq/react

Version:

React bindings for Multisynq

63 lines (62 loc) 2.41 kB
import { useEffect, useState, createElement } from 'react'; import { Session } from '@multisynq/client'; import { MultisynqReactView } from '../MultisynqReactView'; import { MultisynqContext } from './MultisynqContext'; /** Main wrapper component that starts and manages a Multisynq 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 multisynq-react provides a suitable View class behind the scenes. * * ``` * function MyApp() { * return ( * <InMultisynqSession * apiKey='1_123abc', * appId='com.example.myapp' * name='mySession' * password='secret' * model={MyRootModel} * ... * > * // child elements that use hooks go here... * </InMultisynqSession> * ) * } * ``` */ export function InMultisynqSession(params) { const children = params.children; const [multisynqSession, setMultisynqSession] = useState(undefined); const [joining, setJoining] = useState(false); useEffect(() => { console.log('InMultisynqSession effect'); setJoining((old) => { if (old) return old; const sessionParams = Object.assign(Object.assign({}, params), { view: (MultisynqReactView), flags: ['react'] }); delete sessionParams.children; console.log('calling Session.join()'); Session.join(Object.assign({}, sessionParams)).then(setMultisynqSession); return true; }); return () => { // we don't have to reset the session object or such. // The same Multisynq session should be kept during the life time of the page // unless it is explicitly destroyed. // console.log('unmount') }; }, [joining, params]); if (multisynqSession) { const contextValue = { session: multisynqSession, view: multisynqSession.view, model: multisynqSession.view.model, setSession: () => { }, leaveSession: () => { }, sessionParams: params, }; return createElement(MultisynqContext.Provider, { value: contextValue }, children); } return null; }