Skip to content

How it works

  1. State is initiated using a class. This class must be extended from 2n8’s parent class which enhances the store with a few utilities.

    import { TwoAndEight } from '2n8'
    class Store extends TwoAndEight {
    counter = 0
    }
  2. State changes are made inside actions, which are simply class methods.

    import { TwoAndEight } from '2n8'
    class Store extends TwoAndEight {
    counter = 0
    timestamp = 0
    addButtonClicked() {
    this.counter++
    }
    }

    When actions are called, any state mutations are auto committed at the end of the action. If you need to commit early, you can use the special inbuilt this.$commit() action.

    import { TwoAndEight } from '2n8'
    class Store extends TwoAndEight {
    counter = 0
    data: { id: string; title: string }[]
    async addButtonClicked() {
    this.counter++
    this.$commit()
    this.data = await fetchData()
    }
    }
  3. Generate your React hook:

    import { createReactStore } from '2n8'
    const useStore = createReactStore(new Store())

    This uses React’s useSyncExternalStore hook to map committed state to selectors:

    const Component = () => {
    const counter = useStore((s) => s.counter)
    return <div>{counter}</div>
    }

    When, and only when, the selected state changes, the component is rerendered by React. This is more optimal than simply passing state down the component tree via props.

  4. Select and call actions from the store:

    const Component2 = () => {
    const addButtonClicked = useStore((s) => s.addButtonClicked)
    return <button onClick={addButtonClicked}>Add</button>
    }