TinyBase logoTinyBase

Provider

The Provider component is used to wrap part of an application in a context that provides default objects to be used by hooks and components within.

Provider(props: ProviderProps & {children: ReactNode}): ComponentReturnType
TypeDescription
propsProviderProps & {children: ReactNode}

The props for this component.

returnsComponentReturnType

A rendering of the child components.

Store, Metrics, Indexes, Relationships, Queries, and Checkpoints objects can be passed into the context of an application and used throughout. One of each type of object can be provided as a default within the context. Additionally, multiple of each type of object can be provided in an Id-keyed map to the ___ById props.

Provider contexts can be nested and the objects passed in will be merged. For example, if an outer context contains a default Metrics object and an inner context contains only a default Store, both the Metrics objects and the Store will be visible within the inner context. If the outer context contains a Store named by Id and the inner context contains a Store named by a different Id, both will be visible within the inner context.

Examples

This example creates a Provider context into which a Store and a Metrics object are provided, one by default, and one named by Id. Components within it then render content from both, without the need to have them passed as props.

const App = ({store, metrics}) => (
  <Provider store={store} metricsById={{petStore: metrics}}>
    <Pane />
  </Provider>
);
const Pane = () => (
  <span>
    <CellView tableId="species" rowId="dog" cellId="price" />,
    <CellView tableId="species" rowId="cat" cellId="price" />,
    {useMetric('highestPrice', 'petStore')}
  </span>
);

const store = createStore();
store.setTable('species', {dog: {price: 5}, cat: {price: 4}});
const metrics = createMetrics(store);
metrics.setMetricDefinition('highestPrice', 'species', 'max', 'price');

const app = document.createElement('div');
const root = ReactDOMClient.createRoot(app);
root.render(<App store={store} metrics={metrics} />);
console.log(app.innerHTML);
// -> '<span>5,4,5</span>'

This example creates nested Provider contexts into which Store and Metrics objects are provided, showing how visibility is merged.

const App = ({petStore, metrics}) => (
  <Provider storesById={{pet: petStore}} metrics={metrics}>
    <OuterPane />
  </Provider>
);
const OuterPane = () => {
  const planetStore = useCreateStore(() =>
    createStore().setTables({planets: {mars: {moons: 2}}}),
  );
  return (
    <Provider storesById={{planet: planetStore}}>
      <InnerPane />
    </Provider>
  );
};
const InnerPane = () => (
  <span>
    <CellView tableId="species" rowId="dog" cellId="price" store="pet" />,
    {useMetric('highestPrice')},
    <CellView
      tableId="planets"
      rowId="mars"
      cellId="moons"
      store="planet"
    />
  </span>
);

const petStore = createStore();
petStore.setTable('species', {dog: {price: 5}, cat: {price: 4}});
const metrics = createMetrics(petStore);
metrics.setMetricDefinition('highestPrice', 'species', 'max', 'price');

const app = document.createElement('div');
const root = ReactDOMClient.createRoot(app);
root.render(<App petStore={petStore} metrics={metrics} />);
console.log(app.innerHTML);
// -> '<span>5,5,2</span>'