Author: | jsebrech |
---|---|
Views Total: | 23 views |
Official Page: | Go to website |
Last Update: | December 3, 2024 |
License: | MIT |
Preview:

Description:
Tiny Signals is a lightweight JavaScript library that allows you to manage states in vanilla JavaScript projects, inspired by Preact’s Signals API. It provides reactive primitives that keep your application’s data synchronized and your UI updated efficiently.
You define signals that represent pieces of your application’s data. Whenever a signal’s value changes, any part of your code dependent on that signal automatically updates. This reactivity simplifies the process of building dynamic user interfaces and handling complex data interactions.
Consider a common scenario: building a form with multiple input fields where the displayed output depends on the combined values of these inputs. Traditionally, you might manually update the output each time an input changes.
With Tiny Signals, you create signals for each input field and a computed signal that derives the output based on these input signals. Now, the output updates automatically whenever any input value changes, significantly reducing boilerplate code and enhancing maintainability.
How to use it:
1. Download the library and import the necessary modules into your JavaScript file:
import { signal, computed } from './signals.js';
2. Here’s how to create a basic calculator component. In this example:
- We create two signals, a and b, to represent the input values.
- We create a computed signal, result, which automatically calculates the sum of a and b whenever either of them changes.
- Inside the connectedCallback, we set up the HTML structure, including two input fields and a paragraph to display the result.
- The effect function updates the paragraph content with the computed result whenever it changes.
- Finally, an event listener updates the signal values when the user changes the input fields.
<!-- Define a custom element --> <x-adder></x-adder>
customElements.define('x-adder', class extends HTMLElement { // Initialize signals for input values 'a' and 'b' a = signal(1); b = signal(2); // Create a computed signal 'result' that updates automatically result = computed((a, b) => `${a} + ${b} = ${+a + +b}`, [this.a, this.b]); connectedCallback() { // Prevent re-initialization if elements already exist if (this.querySelector('input')) return; // Set up the initial HTML structure this.innerHTML = ` <input type="number" name="a" value="${this.a}"> <input type="number" name="b" value="${this.b}"> <p></p> `; // Update the output paragraph whenever 'result' changes this.result.effect( () => this.querySelector('p').textContent = this.result); // Update the signal values when input fields change this.addEventListener('input', e => this[e.target.name].value = e.target.value); } });
3. API Reference:
// This creates a new signal and initializes it with the provided value. const mySignal = signal(val) // Use this to get the current value of the signal or set a new value. // Setting a new value automatically triggers any dependent effects or computations. mySignal.value // This function registers an effect, which is simply a function (fn) that should run whenever the signal's value changes. // It also immediately executes the function upon registration. // The dispose() function returned from effect allows you to unregister the effect and stop it from running on future signal changes. // It's useful for managing component lifecycles and preventing memory leaks in complex applications. const dispose = mySignal.effect(fn): // This creates a computed signal, which is a signal whose value is derived from other signals or values. // The first argument is a function that computes the new value, and the second argument is an array of dependencies (other signals). // The computed signal automatically updates its value whenever any of its dependencies change. const result = computed(() => mySignal.value, [mySignal]) // This lets you subscribe to changes in the signal's value without immediately calling the function. // The provided function (fn) will execute whenever the signal's value changes. mySignal.addEventListener('change', fn)