Pixel Art Editor - Undo Button
Tags: react, javascript
Published: 2020-12-15 03:16:37

## Introduction

This is my second ever attempt to do something with react, the only thing I've done before is watching some beginner-oriented tutorials and failed to rewrite a card game I've done with unity.

A couple of days ago, a guy named Aleks Popovic posted a tutorial on how to make a pixel art editor in React and it got my attention, as I was working on a pixel art editor earlier this year.

My idea here is to replicate what he did and then expand on it, and the first thing I thought about was an "Undo" function, and to bind it to "Control + Z" so I can draw my beautiful creations with less fear of having to redraw pixel-by-pixel if things are not looking as beautiful as they should.


## The original post

This is the original post where you can find the tutorial:

{% post https://dev.to/alekswritescode/how-to-build-a-pixel-art-drawing-app-in-react-37n8 %}

I don't think this tutorial/post is meant for absolute beginners in React like myself, as I kinda struggled to understand this useState, which I find out is a React Hook.

But I could follow it with little problem after I've googled some basic React concepts.

If you intend to follow it, I would also advise you to read the post while you watch the video, as you can have a little more insight into his thought process.

## Creating the Undo function

### The plan

I knew that in order to create an Undo function, I would have to use a stack of actions.

Whenever an "undoable" action is performed in my app, it should be pushed in a stack with the information needed to undo it.

So when the user calls for this function, I use the information inside the action to undo it and pop my stack.


### The execution

I have first created my stack, it is a simple array bound to the DrawingPanel component: 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/72a5qjqto7t374jl4f5f.png)

And there is my first issue, I did not know how to populate my stack, I found [this tutorial](https://medium.com/@ruthmpardee/passing-data-between-react-components-103ad82ebd17) that explained to me how I could pass the info from the pixels to my main component, so that's what I did:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/q8fjxzmibzakrdtxbul1.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/lcknkk5577hrj9ae0g94.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/7arjhxmg0b20glg5ysa8.png)

And if you followed his tutorial you probably realized that I have butchered his code already, ahahah

So, I kept having a bug where the colors would randomly change in other pixels after I clicked any of them. I realized that if I removed the oldColor variable the bug just stopped. As it is really late, I don't want to dive in and fix it right now, I will leave it without the "color preview" feature it originally had.

Moving on;

I removed the export button because I don't mean to export my arts, they are meant only for myself and I proceeded to create the Undo button:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/6v7wb3i1iqbfkvj7ofya.png)

The Undo button calls this function:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ewshjycb9whtfgr4710n.png)

Ignore the useCallback for now, I will get there;

This function gets the last action in the stack, calls the undo function in the pixel component, and then pops the stack, as I've described in the "plan" section of this post.

Alright, with that I had my function working, the last thing I had to do was to bind it to Control + Z.

In order to do that, I had to study some other React functions:

useEffect and useCallback

useEffect allowed me to bind a document event to a function inside my component, so I told it to listen to keyCode 26 (that is Control + Z) and to call undo;

However, once I did that, there was a warning in my console, telling me that it would create a new instance of Undo every time that component updated.

And that is when I found out about useCallback which is a function that saves the value from another function and keeps it the same as long as the input is the same.

And with that, I've finished my Undo function.

I am really liking React, can see how it became so popular

I will probably create some more functions for this app in the future.

This is the repository for what I've done in this post:

{% github ciochetta/study-react no-readme %}