Three months after getting this beautiful model for my birthday, I’m calling it finished. Here’s my Dread Saurian.
I ran into an issue with my side project AoS Reminders recently where I was mutating an object that wasn’t supposed to be mutated.
I was having trouble tracking down the mutation, until I stumbled upon the Proxy
object, a helpful tool for any Javascript developer.
This can be useful for detecting when your objects are being accessed.
Another great example of using Proxy
is for object validation:
While useful, you should really be using Typescript and enforcing your object keys that way ;)
Hope this helps someone! Just thought I’d share a small, neat feature of JS I hadn’t used before.
In this post, I’d like to convince you to use Immer, 2019’s hottest JavaScript framework.
Immer is a tiny package that allows you to work with immutable state in a more convenient way.
The basic idea is that you will apply all your changes to a temporary draftState
, which is a proxy of the currentState
. Once all your mutations are completed, Immer will produce the nextState
based on the mutations to the draftState
. This means that you can interact with your data by simply modifying it while keeping all the benefits of immutable data.
We write a lot of boilerplate when using Redux and updating our store. Every developer familiar with even remotely complex reducers has seen this pattern before:
All that code just to set one entry to completed: true
! This “extra” destructuring work is required because Redux needs us to return a complete copy of the state.
What if we could just modify the entry we want, and Redux could figure out the rest? Well, that may be expecting too much of Redux, but luckily, we can now use Immer!
With Immer, the above code would look like:
From a developer point of view, I think the benefits are obvious. We’re no longer spending time trying to destructure and then restructure state. We’re just performing a simple operation and moving on with our lives.
To begin with, what does an Immer function even look like?
Here’s an example:
Okay, let’s do something a little more realistic. Let’s pretend we’re building an app where users can check a certain field. A todo list or grocery shopping app would make sense.
I think you’re probably starting to get the idea. But let’s get into why this would work for advanced applications where you’re using and abusing Redux heavily.
Here is a real example of a very painful piece of code that we had written at work. We have a UX flow that allows the user to change the height
of a displayed chart. The only thing this action handler wants to do is update the height
property of a specific chart. But unfortunately, we have to fully recreate the state via destructuring - and it gets ugly!
Ugh! That is pretty gross. Let’s use Immer instead.
Boom! The exact same functionality as above.
(If this example doesn’t win you over, I have nothing to offer you.)
Guess which one is easier to understand? Guess which one doesn’t take 15 minutes and two developers to write? (True story).
Let’s refactor another action handler - this one deletes a single entry in the store.
Is that super dope or what? We accomplish the same task with two lines of code.
Immer does have a downside - namely, it’s about twice as slow as a well-written reducer. Immer recommends not using this library when operating on tens of thousands of objects - otherwise, the performance difference is neglible.
Use Immer wherever it makes sense to you. It’s easy to start with, and the developer benefits will become clear immediately. Your functions will also become easier to test and debug, since you’ll be rid of the noise that comes along with re-creating state all the time!
For those of you using TypeScript - the Immer library is strongly typed! Very cool!
If you’ve ever worked with a multi-page React app, you will invariably run into the dreaded warning in your console:
Warning: Can't perform a React state update on an unmounted component.
The most common cause of this warning is when a user kicks off an asynchronous request, but leaves the page before it completes. I especially wanted to know how to do this with hooks, because hooks are awesome.
I wanted to know how to avoid this classic React warning - here’s my solution.
To explain the above code snippet, imagine we have a sample component that simply displays a counter, and a button to increment the counter.
When we click the button, it fires off someLongRunningProcess()
- this could be a backend operation or whatever. Use your imagination.
When someLongRunningProcess()
has completed, we make sure we’re still mounted via the componentIsMounted
variable! If the component is still mounted, we can modify the state, no problem. If it’s not mounted - hey, that’s alright, we won’t touch the state.
This will dodge that nasty React warning! Have fun!