Giter Site home page Giter Site logo

b8zeek / proxy-state-mgmt Goto Github PK

View Code? Open in Web Editor NEW

This project forked from bennyhinrichs/proxy-state-mgmt

0.0 0.0 0.0 34 KB

Uses the JS object proxy for a very simple state management to be used with web components

HTML 18.13% JavaScript 73.13% CSS 8.74%

proxy-state-mgmt's Introduction

Overview

You only have a few things to keep track of. You don't want to load a whole library like Redux or MobX to manage your state. Well try this method instead. It takes advantage of JavaScript object proxies to let you subscribe to individual properties on the global state. With this, everything is stored on your custom element as properties instead of attributes (so no attributeChangedCallback). It assumes that if you care enough to wed an element to the state, you'll have no issues in making a custom element of it.

Properties Reflect State

Sometimes you need your elements to be carrying the live data. Maybe you have a bunch of form fields that you need to collect data from at once. You wouldn't want to have to go to the state and try and map all of the properties to inputs. You would just want to grab all the fields and their data in one easy swoop. In a case like this, you'll want to mirror the state onto the element's properties.

Usage

  1. Make thee a custom element that extends my SubscriberElement class.
  2. Define the class field observedProperties, a Set of properties you want to observe. You can do this in the constructor if you want it more backward-compatible.
  3. Define the render() method.
  4. If needed, override connectedCallback.
  5. If needed, override propertyChangedCallback.
  6. Make getters and setters for each property. This could potentially be done in the subscribeToProp method, but I don't know if I want to take that flexibility away from the programmer.
  7. If for whatever reason you need to stop listening to state changes for a certain prop, you can call unsubscribeFromProp, passing in the name of the undesired prop.

State Only

This method is preferred for most cases I run into. Sometimes you don't care that the element itself is carrying the data simply accessing it from elsewhere is fine. The most salient case is where the state is only affecting the visual aspect of your components. Such instances lend themselves very well to shielding your elements from the burden of bearing the state.

Usage

The exact same as the Properties Reflect State version, except you don't need to make getters and setters (unless you're watching local attributes in addition to the global properties).

Both

If you look at the two subscriber-element.js files, you'll notice they only differ by a constructor. You could extend the State Only SubscriberElement, add the constructor, and call that one something like SubscriberWithProps. Then you can use both in one app.

If you want to do this, you'll have to modify state.js to include a check to see which element it's extending. That would look like

set: (target, prop, value, receiver) => {
  const sameObj = typeof value === 'object' && equal(value, target[prop])
  if (sameObj || target[prop] === value) return true
  const oldValue = target[prop]
  target[prop] = value
  if (subscribers[prop]) {
    subscribers[prop].forEach(s => {
      // here's the exciting part
      if (Object.getPrototypeOf(Object.getPrototypeOf(s)).constructor.name === 'SubscriberElement') {
        s.propertyChangedCallback(prop, oldValue, value)
      } else {
        s[prop] = value
      }
    })
  }
  return true
}
Object.getPrototypeOf(Object.getPrototypeOf($0)).constructor.name

Extras

Server Integration

A beautiful aspect of this is that it's source-agnostic; it doesn't care where the change came from. You can receive an update from the server as JSON, parse and push it, and all your elements will get updated. I haven't done any testing in that regard.

Rich Data, JS Optionals

Optional chaning is in, boys. That means you can check for data like obj?.level1?.level2?.level3?.key. Isn't that just lovely? Anyway, the point is don't pass in rich data (like an object), then shoot yourself in the foot by not doing null checks on it.

Smart render()

What should go in my render function? How do I make it smart? My first suggestion is to split your visual updates into two categories: content and style. If a visual update can be achieved by adding or removing a class, do that instead of resetting the entire this.innerHTML.

One idea is to have a firstRender function called inside of connectedCallback. Inside of this, you set this.innerHTML to the initial render, then you go through and create a registry of every node as a property on the element. Then inside of propertyChangedCallback you write it so that it only alters the nodes relevant to the updated property. Since they're already stored in a registry, there's no need for querySelector.

Easy Web Server for Chrome

If you want to try out the demo but don't want to start up some command line server, try out Web Server for Chrome. Clone the repo, then point that server to the folder.

Help, I'm Lost!

State management is when you have one piece of data that multiple components on your page need to know about all at the same time. An easy example is just the current page. You might want different components to render differently based on which view of your app the user is on. All of those components need to know what page you're switching to at the same time. So you keep that data in a central location and send out patches. Imagine your mom texting the family that dinner is ready. She only had to do one action, but every individual decides how they react to this update.

proxy-state-mgmt's People

Contributors

bennyhinrichs avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.