TinyBase logoTinyBase β

useCreateRelationships

The useCreateRelationships hook is used to create a Relationships object within a React application with convenient memoization.

useCreateRelationships(
  store: undefined | Store,
  create: (store: Store) => Relationships,
  createDeps?: DependencyList,
): Relationships | undefined
TypeDescription
storeundefined | Store

A reference to the Store for which to create a new Relationships object.

create(store: Store) => Relationships

An optional callback for performing post-creation steps on the Relationships object, such as adding definitions or listeners.

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.

returnsRelationships | undefined

A reference to the Relationships object.

It is possible to create a Relationships object outside of the React app with the regular createRelationships 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 Relationships object being created every time the app renders or re-renders, since v5.0 this hook performs the creation in an effect. As a result it will return undefined on the brief first render (or if the Store is not yet defined), which you should defend against.

If your create function contains other dependencies, the changing of which should also cause the Relationships object to be recreated, you can provide them in an array in the optional second parameter, just as you would for any React hook with dependencies.

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

Examples

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

import {createRelationships, createStore} from 'tinybase';
import {useCreateRelationships, useCreateStore} from 'tinybase/ui-react';
import React from 'react';
import {createRoot} from 'react-dom/client';

const App = () => {
  const store = useCreateStore(() =>
    createStore()
      .setTable('pets', {
        fido: {species: 'dog'},
        felix: {species: 'cat'},
        cujo: {species: 'dog'},
      })
      .setTable('species', {dog: {price: 5}, cat: {price: 4}}),
  );
  const relationships = useCreateRelationships(store, (store) => {
    console.log('Relationships created');
    return createRelationships(store).setRelationshipDefinition(
      'petSpecies',
      'pets',
      'species',
      'species',
    );
  });
  return (
    <span>{relationships?.getRemoteRowId('petSpecies', 'fido')}</span>
  );
};

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

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

console.log(app.innerHTML);
// -> '<span>dog</span>'

This example creates a Relationships object at the top level of a React application. The App component is rendered twice, each with a different top-level prop. The useCreateRelationships hook takes the remoteTableAndCellToLink prop as a dependency, and so the Relationships object is created again on the second render.

import {createRelationships, createStore} from 'tinybase';
import {useCreateRelationships, useCreateStore} from 'tinybase/ui-react';
import React from 'react';
import {createRoot} from 'react-dom/client';

const App = ({remoteTableAndCellToLink}) => {
  const store = useCreateStore(() =>
    createStore()
      .setTable('pets', {
        fido: {species: 'dog', color: 'brown'},
        felix: {species: 'cat', color: 'black'},
        cujo: {species: 'dog', color: 'brown'},
      })
      .setTable('species', {dog: {price: 5}, cat: {price: 4}})
      .setTable('color', {brown: {discount: 0.1}, black: {discount: 0}}),
  );
  const relationships = useCreateRelationships(
    store,
    (store) => {
      console.log(`Relationship created to ${remoteTableAndCellToLink}`);
      return createRelationships(store).setRelationshipDefinition(
        'cellLinked',
        'pets',
        remoteTableAndCellToLink,
        remoteTableAndCellToLink,
      );
    },
    [remoteTableAndCellToLink],
  );
  return (
    <span>{relationships?.getRemoteRowId('cellLinked', 'fido')}</span>
  );
};

const app = document.createElement('div');
const root = createRoot(app);
root.render(<App remoteTableAndCellToLink="species" />);
// -> 'Relationship created to species'

console.log(app.innerHTML);
// -> '<span>dog</span>'

root.render(<App remoteTableAndCellToLink="color" />);
// -> 'Relationship created to color'

console.log(app.innerHTML);
// -> '<span>brown</span>'

Since

v1.0.0