Undo Actions on State by Implementing an undoHistory Feature with Jotai Atoms

Daishi Kato
InstructorDaishi Kato
Share this video with your friends

Social Share Links

Send Tweet
Published 3 years ago
Updated 3 years ago

Often times you'll want the user of your application to be able to undo an action that they've taken. Adding this feature requires you to keep track of the actions that have occurred and what state the application was in at each action.

To solve this, you'll need to store the history in some way. With Jotai, because the atoms that you are using are immutable you can save a snapshot of an atom when an action is taken and store that for use later on.

We will replace the previous shapesAtomsAtom that stored the array of our svg shapes with a historyAtom that will add each snapshot of the canvas to an array. We can then export a new shapesAtomsAtom that will behave exactly like the previous one as well as a saveHistoryAtom that we can use when we update our state. This will allow implementing an undoHistory atom that will remove any shapes or colors that we don't want to use on our canvas.

Daishi Kato: [0:00] We define ShapeAtomValue and ShapeAtom's types. ShapeAtomValue is an immutable object, and we can safety store it in history. In the new history.ts file, we define internalShapeAtomsAtom and historyAtom. Both are primitive atoms and not exported.

[0:22] Next is to create saveHistoryAtom. It will read internalShapeAtomsAtom and create an immutable snapshot array and add it into the beginning of the historyAtom. Then, create shapeAtomsAtom, which behaves exactly like a primitive atom, but it saves history before updating internalShapeAtomsAtom.

[0:47] Lastly, we define undoAtom. It returns hasHistory as its value for disabling button. On write, it will restore internalShapeAtomsAtom with the first item in the historyAtom. In SvgShapes.tsx, all we need is to replace shapeAtomsAtom with the one defined in history.ts.

[1:09] Finally, in Controls.tsx, we import undo atom and define the Undo button. The button is disabled when there is no history. Let's try how it works. See? It's working well.

[1:24] Now, what we want to undo, changing colors. Let's modify selection.ts. Import { saveHistoryAtom } and invoke it before changing the color. This allows us to undo changing color too. Technically, we could improve it to undo selection and also add redo feature.

[1:45] In summary, we created a new history.ts file and defined a new shapeAtomsAtom. This replaces the original shapeAtomsAtom in SvgShapes.tsx and saves history before the change. The change in SvgShapes.tsx was minimal. We also enabled undo changing colors. You are free to extend the history feature more.

egghead
egghead
~ 23 minutes ago

Member comments are a way for members to communicate, interact, and ask questions about a lesson.

The instructor or someone from the community might respond to your question Here are a few basic guidelines to commenting on egghead.io

Be on-Topic

Comments are for discussing a lesson. If you're having a general issue with the website functionality, please contact us at support@egghead.io.

Avoid meta-discussion

  • This was great!
  • This was horrible!
  • I didn't like this because it didn't match my skill level.
  • +1 It will likely be deleted as spam.

Code Problems?

Should be accompanied by code! Codesandbox or Stackblitz provide a way to share code and discuss it in context

Details and Context

Vague question? Vague answer. Any details and context you can provide will lure more interesting answers!

Markdown supported.
Become a member to join the discussionEnroll Today