TinyBase logoTinyBase

useCreateSynchronizer

The useCreateSynchronizer hook is used to create a Synchronizer within a React application along with convenient memoization and callbacks.

useCreateSynchronizer<SynchronizerOrUndefined>(
  store: undefined | MergeableStore,
  create: (store: MergeableStore) => Promise<SynchronizerOrUndefined>,
  createDeps?: DependencyList,
  destroy?: (synchronizer: Synchronizer) => void,
  destroyDeps?: DependencyList,
): SynchronizerOrUndefined
TypeDescription
storeundefined | MergeableStore

A reference to the MergeableStore for which to create a new Synchronizer object.

create(store: MergeableStore) => Promise<SynchronizerOrUndefined>

An asynchronous function for performing the creation steps of the Synchronizer object for the Store.

createDeps?DependencyList

An optional array of dependencies for the create function, which, if any change, result in its rerun. This parameter defaults to an empty array.

destroy?(synchronizer: Synchronizer) => void

An optional callback whenever the Synchronizer is destroyed due to a change in the createDeps dependencies.

destroyDeps?DependencyList

An optional array of dependencies for the destroy callback, which, if any change, result in destroy and then being rerun. This parameter defaults to an empty array.

returnsSynchronizerOrUndefined

A reference to the Synchronizer.

It is possible to create a Synchronizer outside of the React app with the regular createSynchronizer function and pass it in, but you may prefer to create it within the app, perhaps inside the top-level component. To prevent a new Synchronizer being created every time the app renders or re-renders, the useCreateSynchronizer hook performs the creation in an effect.

If your asynchronous create function (the second parameter to the hook) contains dependencies, the changing of which should cause the Synchronizer to be recreated, you can provide them in an array in the third parameter, just as you would for any React hook with dependencies. The MergeableStore passed in as the first parameter of this hook is used as a dependency by default.

The create function can return undefined, meaning that you can enable or disable synchronization conditionally within this hook. This is useful for applications which might turn on or off their cloud synchronization or collaboration features.

This hook ensures the Synchronizer object is destroyed whenever a new one is created or the component is unmounted.

Examples

This example creates a Synchronizer at the top level of a React application. Even though the App component is rendered twice, the Synchronizer creation only occurs once by default.

import {
  useCreateMergeableStore,
  useCreateSynchronizer,
  useTables,
} from 'tinybase/ui-react';
import React from 'react';
import {createLocalSynchronizer} from 'tinybase/synchronizers/synchronizer-local';
import {createMergeableStore} from 'tinybase';
import {createRoot} from 'react-dom/client';

const App = () => {
  const store = useCreateMergeableStore(() => createMergeableStore('s1'));
  useCreateSynchronizer(store, async (store) => {
    console.log('Synchronizer created');
    return await createLocalSynchronizer(store, 'pets');
  });
  return <span>{JSON.stringify(useTables(store))}</span>;
};

const app = document.createElement('div');
const root = createRoot(app);
root.render(<App />);
// -> 'Synchronizer created'

// ...
root.render(<App />);
// No second Synchronizer creation

root.unmount();

This example creates a Synchronizer at the top level of a React application. The App component is rendered twice, each with a different top-level prop. The useCreateSynchronizer hook takes the url prop as a dependency, and so the Synchronizer object is created again on the second render. The first is destroyed and the destroy parameter is called for it. A then parameter is provided to start both Synchronizers' synchronization.

import {
  useCreateMergeableStore,
  useCreateSynchronizer,
  useTables,
} from 'tinybase/ui-react';
import React from 'react';
import {WebSocketServer} from 'ws';
import {createMergeableStore} from 'tinybase';
import {createRoot} from 'react-dom/client';
import {createWsServer} from 'tinybase/synchronizers/synchronizer-ws-server';
import {createWsSynchronizer} from 'tinybase/synchronizers/synchronizer-ws-client';

const server1 = createWsServer(new WebSocketServer({port: 8044}));
const server2 = createWsServer(new WebSocketServer({port: 8045}));

const App = ({url}) => {
  const store = useCreateMergeableStore(() => createMergeableStore('s1'));
  useCreateSynchronizer(
    store,
    async (store) => {
      const webSocket = new WebSocket(url);
      console.log(`Synchronizer created for ${webSocket.url}`);
      return await createWsSynchronizer(store, webSocket);
    },
    [url],
    (synchronizer) => {
      const webSocket = synchronizer.getWebSocket();
      console.log(`Synchronizer destroyed for ${webSocket.url}`);
    },
  );
  return <span>{JSON.stringify(useTables(store))}</span>;
};

const app = document.createElement('div');
const root = createRoot(app);
root.render(<App url="ws://localhost:8044/" />);
// ...
// -> 'Synchronizer created for ws://localhost:8044/'

root.render(<App url="ws://localhost:8045/" />);
// ...
// -> 'Synchronizer created for ws://localhost:8045/'
// -> 'Synchronizer destroyed for ws://localhost:8044/'

root.unmount();
// -> 'Synchronizer destroyed for ws://localhost:8045/'

server1.destroy();
server2.destroy();

Since

v5.0.0