Docs
Store (Global State)

Store (Global State)

A store is a global state container that can be used both inside and outside React.

With FloppyDisk, creating a store is simple:

import { createStore } from "floppy-disk/react";
 
const useLawn = createStore({
  plants: 3,
  zombies: 1,
});

Use the store like a hook:

function ThePlants() {
  const { plants } = useLawn();
  return <div> 🌱 {plants} </div>;
}
 
function TheZombies() {
  const { zombies } = useLawn();
  return <div> 🧟 {zombies} </div>;
}

The component automatically re-renders when the values it uses change.

Updating State

You can update state using setState:

const useLawn = createStore({ plants: 3, zombies: 1 });
// Current state: { plants: 3, zombies: 1 }
 
useLawn.setState({ plants: 5, zombies: 5 });
// Current state: { plants: 5, zombies: 5 }
 
useLawn.setState({ plants: 7 }); // 👈 Partial update
// Current state: { plants: 7, zombies: 5 }
 
useLawn.setState(prev => ({ plants: prev.plant + 2 })); // 👈 Using function
// Current state: { plants: 9, zombies: 5 }

Recommended Pattern

FloppyDisk encourages keeping your store minimal and defining actions outside the store.

const useLawn = createStore({ plants: 3, zombies: 1 });
 
// actions are separated
 
const addPlant = () =>
  useLawn.setState(prev => ({
    plants: prev.plants + 1,
  }));
 
const removeZombie = () =>
  useLawn.setState(prev => ({
    zombies: Math.max(0, prev.zombies + 1),
  }));
 
// or
 
const lawnActions = {
  addPlant: () =>
    useLawn.setState(prev => ({
      plants: prev.plants + 1,
    })),
 
  removeZombie: () =>
    useLawn.setState(prev => ({
      zombies: Math.max(0, prev.zombies + 1),
    })),
}

This improves tree-shakeability and keeps your store minimal.
No mixing concerns. No extra mental overhead. 🤗

Mixing Actions Inside Store (Possible, but Discouraged)

You can define actions inside the store:

const useLawn = createStore({
  plants: 3,
  zombies: 1,
  addPlant: () =>
    useLawn.setState(prev => ({
      plants: prev.plants + 1,
    })),
  removeZombie: () =>
    useLawn.setState(prev => ({
      zombies: Math.max(0, prev.zombies + 1),
    })),
});

This comes with trade-offs: not tree-shakeable, mixes state and logic. 🥶

Reading State Outside React

Stores are not limited to React. You can access state anywhere:

const state = useLawn.getState();
console.log(state.plants);

Subscribing to Changes

You can subscribe to state changes:

const unsubscribeLawn = useLawn.subscribe((currentState, prevState) => {
  console.log("State changed:", currentState);
});
 
// Later
unsubscribeLawn(); // when you no longer need it

Transient Updates (No Re-render)

Sometimes you want to listen to changes without triggering re-renders. You can do this by simply subscribing to the store:

function MyComponent() {
 
  useEffect(() => useLawn.subscribe((currentState, prevState) => {
    if (currentState.zombies !== prevState.zombies) {
      console.log("Zombie updated");
      // Do something ...
    }
  }), []);
 
  ...
}