0.0.2 • Published 2 years ago

lit-shared-state-test v0.0.2

Weekly downloads
-
License
MIT
Repository
-
Last release
2 years ago

Lit Shared State

The easiest way to share global state between LitElement instances

Note: requires lit@2.x

Highlights

lit-shared state was built to be..

  • ..reactive - state that can be shared across
  • ..simple - extremely minimal api surface, not much doc required :)
  • ..performant - lazy: only relevant slices of state lead to updates
  • ..flexible - state storage can be customized (for instance to use localstorage etc..)
  • ..tiny - less than 150 lines of commented typescript (~1KB minified), no dependencies (except for lit)

Installation

npm install lit-shared-state

Usage

import { LitElement, html } from "lit";
// this is all you need
import { state } from "lit-shared-state";

class State {
  // one line to declare anything as state
  // any subsequent change will redraw
  // all components that depend on it
  @state reactiveState: number = 1;
  // ..
}
const globalState = new State();

class CompA extends LitElement {
  // one line to pull in a slice of state
  @state state = globalState;

  render() {
    return html`<button @click=${() => this.state.reactiveState++}>
        ${this.state.reactiveState}
    </button>`;
  }
}

class CompB extends LitElement {
  // use state in multiple components
  @state state = globalState;

  render() {
    return html`<div> I am in sync:
        ${this.state.reactiveState}
    </div>`;
  }
}

// manipulating state from anywhere wills
// lead to update for all LitElements that depend on it
globalState.reactiveState += 41;

Gotchas

Updating nested objects

Updating nested fields in @state-annotated properties will not trigger a rerender (behavior is the same as in LitElement).

class State {
  @state object: { a: 'a', b: 'b' };
  @state array: ['a', 'b'];
}
const myState = new State();

// these will not trigger updates:
myState.object.c = 'c';
myState.array.push('c');

// instead use explicit assignment (+ spread operators) like this:
myState.object = { ...myState.object, c: 'c' };
myState.array = [ ...myState.object, 'c' ];

How does it compare

lit-element-state

This project is heavily inspired by https://github.com/gitaarik/lit-state. And has a very similar feature set and scope. The main difference is that we ..

  • .. provide typescript implementation
  • .. rely a less intrusive lit 2.x ReactiveController pattern
  • .. provide unit-tested code with 100% coverage