DEV Community

M. Andrew Darts
M. Andrew Darts

Posted on

7 4

Vanilla change detection with Proxies in Javascript

In a smaller project with just a little interactivity you may want to keep up with a bit of state. If you have worked with Redux, MobX, NGRX or any other state management library your first inclination may be to use what you are familiar with. Let's be cheap and look to the platform and see what tools we can use to get this done without a library.

Proxies

Proxies are somewhat a new concept in Javascript. Proxies simply provide a way to enhance an object, some examples are listeners, dynamic properties and validation. Quick example.


const person = { firstName: "Luke", lastName: "Skywalker" };


const personHandler = {
  set: function(obj, prop, value) {
   console.log(`${prop} changed from ${obj[prop]} to ${value}`);
   obj[prop] = value;
   return true;
  }
};


const personProxy = new Proxy(person, personHandler);

personProxy.firstName = "Not Luke";
// console.logs "firstName changed from Luke to Not Luke";

Enter fullscreen mode Exit fullscreen mode

In just 10 lines of code we have implemented a simple proxy that logs the changes of an object.

One small step

Let's take this a step further. Say we want to keep up with a list of notes. These notes will need to be rendered on the page. We need a simple way to update the notes array and those changes be reflected to the page without thinking. If we think about it the data is the source of truth and the rendering is a side effect. That being said let's create a Proxy factory that will take in an object to observe and an array of functions to run when the object changes.

export const observer = (obj, ...listeners) => {
  return new Proxy(obj, {
    set: function(obj, prop, value) {
      listeners.forEach(fn => fn({...obj, [prop]: value}, obj));
      obj[prop] = value;
      return true;
    }
  })
}

Enter fullscreen mode Exit fullscreen mode

What is this ☝️?
This is a factory function that will create proxies and run some functions when it changes. How do I use this?

const notesObserver = observer(
 { notes: [{ text: "Do something." }] }, 
 renderNotes,
 logChanges
);

function renderNotes(notes) {
  // render notes here...
}

function logChanges(notes, oldNotes) {
  console.log(notes, oldNotes);
}
Enter fullscreen mode Exit fullscreen mode

Below is a working example. As the web platform grows things will only get more exciting! Think of all the cool things that could be done with Proxies. Would love to hear thoughts and ideas!

Here is an example of the notes app working with Proxies.

Do your career a big favor. Join DEV. (The website you're on right now)

It takes one minute, it's free, and is worth it for your career.

Get started

Community matters

Top comments (0)

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

👋 Kindness is contagious

Dive into an ocean of knowledge with this thought-provoking post, revered deeply within the supportive DEV Community. Developers of all levels are welcome to join and enhance our collective intelligence.

Saying a simple "thank you" can brighten someone's day. Share your gratitude in the comments below!

On DEV, sharing ideas eases our path and fortifies our community connections. Found this helpful? Sending a quick thanks to the author can be profoundly valued.

Okay