jotai-sync-scope
TypeScript icon, indicating that this package has built-in type declarations

0.0.1 • Public • Published

The idea is to sync two Jotai atoms by basically making writing to synced atom to write to original atom.

Definitions

  • source atom - atom that is declared/used higher in React tree
  • target atom - atom that should be synced with source atom meaning that writing to it will write the same value to the source atom

Backwards should work too. Writing to source atom should change value in target atom

Rules

  • If the atom is not synced writing to it means writing to original atom
  • If the atom is target atom then writing operation writes to associated source atom
  • If the atom is source atom then writing operation writes to the atom and target atom is updated automatically because target atom is basically the reference to source atom

Usage

import { atom, useAtom } from 'jotai';
import { SyncScopeProvider } from 'jotai-sync-scope';

const sourceAtom = atom(0);
const targetAtom = atom(0);

const App = () => {
  const [state] = useAtom(sourceAtom);

  return (
    <>
      <p>Source: {state}</p>
      <Sync />
    </>
  );
};

const Sync = (props) => {
  return (
    <SyncScopeProvider atoms={[[sourceAtom, targetAtom]]}>
      <Component />
    </SyncScopeProvider>
  );
};

const Component = () => {
  const [state, setState] = useAtom(targetAtom);

  return (
    <>
      <p>Target: {state}</p>
      <button onClick={() => setState((s) => s + 1)}>+1</button>
    </>
  );
};

Use case

One of the use cases is when you have atom with array of items and you want to provide a way to consume item within scope of some components using splitAtom and hook to the item like it's global.

import { atom, useAtom, useAtomValue, atom } from 'jotai';
import { splitAtom } from 'jotai/utils';
import { SyncScopeProvider } from 'jotai-sync-scope';

const tabsAtom = atom([]);
const tabAtomsAtom = splitAtom(tabsAtom);

const App = () => {
  const tabAtoms = useAtomValue(tabAtomsAtom);

  return (
    <>
      {tabAtoms.map((atom) => (
        <SyncScopeProvider atoms={[[atom, tabAtom]]} key={atom.key}>
          <Tab />
        </SyncScopeProvider>
      ))}
    </>
  );
};

const tabAtom = atom({});

const Tab = () => {
  const [tab, setTab] = useAtom(tabAtom);

  // You can update tabAtom value as if it's global but it's actually relates to an item from tabsAtom.
};

// You can even derive some state from tabAtom and use it to access some part of it
const tabName = atom((get) => get(tabAtom).title);

Readme

Keywords

Package Sidebar

Install

npm i jotai-sync-scope

Weekly Downloads

1

Version

0.0.1

License

MIT

Unpacked Size

12 kB

Total Files

8

Last publish

Collaborators

  • okinazuno