Share State Between Frontend Modules

In general, state in React apps should be managed using React(opens in a new tab). Use the State Hook(opens in a new tab) (or Reducer Hook(opens in a new tab)) and Context(opens in a new tab) to pass state around within your frontend module.

In some cases, you may need to manage state outside React, such as when you have separate React applications that need to share state. This can come up, for example, if you your frontend module has multiple extensions that need to share state with each other.

In these cases you can use the @openmrs/esm-state(opens in a new tab) features of @openmrs/esm-framework. The framework provides functions for managing state using Zustand(opens in a new tab).

Usage

A Zustand store can be created using createGlobalStore(opens in a new tab):

import { createGlobalStore } from "@openmrs/esm-framework"; export interface BooksStore { books: Array<string>;} createGlobalStore("books", { books: [],});

The store can then be accessed using getGlobalStore(opens in a new tab)

import { getGlobalStore } from "@openmrs/esm-framework"; const bookStore = getGlobalStore("books");console.log(bookStore.getState());bookStore.subscribe((books) => console.log(books));bookStore.setState({ books: ["Pathologies of Power"] });

In React:

import React, { useEffect } from "react";import { getGlobalStore, useStore } from "@openmrs/esm-framework"; const bookStore = getGlobalStore("books"); function BookShelf() { const { books } = useStore(bookStore); return <>{books.join(",")}</>;}

There are a few other ways that you can use stores in React, such as by creating a subscription in a useEffect block, or by using Provider and connect, but this method is by far the simplest.

Other notes

If your directory structure allows, you can also pass stores around explicitly:

bookStore.ts

See the Zustand docs(opens in a new tab) for more information about stores.

Related pages