Introducing rko, a three-letter state management library for #reactjs with built-in undo, redo, and local persistence. Built on @pmndrs zustand. github.com/steveruizok/rko.
The idea here is to update state either with a "patch", or a deep partial of the state containing only the changes that you want to make...
...or else a "command" made up of two patches, before and after. Only commands become part of the undo/redo stack.
Patches are deep-merged into the previous state. In a command, the after patch is merged in right away. On undo, a command's before patch gets merged in. On redo, the after gets merged in again.
Normally, the "before" of a command just preserves the current values from the state. But you can also use it to restore earlier parts of the state, e.g. the value of a text field from before the user started editing it.
The lib is really straightforward: extend the `StateManager` class and add on methods specific to your app. (See the example for, uh, an example). Then call the methods from your app, and select out the state you need ala zustand.
The state is persisted to local storage, with some basic versioning and upgrade functionality. This is an extraction / simplification of the state I'm using for @tldraw. I'll probably go back this week and plug this in instead!
(er, not local storage, indexdb via @jaffathecake 's idb-keyval)
Just bumped with a `replaceState` method, that works like `patchState` but takes a full state instead of a patch. (This is also how the setter function of a `useState` hook works too, I guess.) Nice for moments when big fast changes are happening and deep merging would be slow.
In general though, the merges are pretty fast. The merge function I'm using is "sorta deep", meaning that it doesn't get into merging arrays or other tricky parts of a library (like deep-merge).
It's also not as defensive, so don't go merging Date objects or things like that.
The point is to avoid dropping frames while updating the state rapidly, ie while scrubbing a value or dragging lots of items.
Updating the undo/redo stack must still use commands, which involve merging patches; however, you would usually only update the undo/redo stack at the end of a rapid-update session (not during it) at which point dropping a frame wouldn't be noticeable.
Share this Scrolly Tale with your friends.
A Scrolly Tale is a new way to read Twitter threads with a more visually immersive experience.
Discover more beautiful Scrolly Tales like this.