npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-observable-connect

v1.2.0

Published

react-observable-connect provides a way for you to connect the state of any Observable object to the props of your React components.

Downloads

27

Readme

react-observable-connect · GitHub license npm version Build Status

react-observable-connect provides a way for you to connect the state of any Observable object to the props of your React components.

You can think of this similar to react-redux's connect function, but it allows you to use any Observable object as the source instead of just the redux store. Also, different React components throughout your app can subscribe to different Observables.

Installation

react-observable-connect is available under the react-observable-connect package on npm.

npm install --save react-observable-connect

Usage

Recall that part of the Observable spec is that an Observable object has a subscribe method which receives a callback and returns an object containing an unsubscribe method. Anytime the Observable object has a status update, the callback passed to the subscribe method gets called. Once the unsubscribe method is called, the callback isn't called anymore.

The full Observable spec is more complicated than that, but any JavaScript object that matches the below interface will be compatible with this library (note that this is a subset of the interface for the full spec, tc39/proposal-observable)

interface Observable {

  // Subscribes to state changes in the observable with a callback
  subscribe(onNext : Function) : Subscription;

}

interface Subscription {

  // Cancels the subscription
  unsubscribe() : void;

}

Check out the following quick example of an Observable object's behavior:

// Model matches the Observable interface
const model = new Model();

function printModelFoo() {
  console.log(model.getFoo());
}

// When anything in the model changes, the value of foo in the model will be printed to the console
const subscription = model.subscribe(printModelFoo);

// Change the model using one of the methods on it
model.setFoo("bar");
// console output: bar

model.setFoo("fizzbuzz");
// console output: fizzbuzz

// Although foo wasn't changed, the subscription's callback will still be called
model.setBar("bat");
// console output: fizzbuzz

subscription.unsubscribe();

model.setFoo("bat");
// There is no console output because we have unsubscribed from the Observable

In an MVC-designed app, your model is the single source of truth for data, so you want to be able to connect your models to your views so that changes in one reflect to the other. As long as your model is Observable, this library will help you do that. Also, this library will help you make your models Observable.

If you define functions objToValueProps and objToFuncProps, you can link the props of a React component with any Observable object. Anytime the Observable object changes, objToValueProps will be run and if the result is different than the last call, the component will be re-rendered with the new props.

import React from 'react';
import connect from 'react-observable-connect';

function DumbModelView(props) {
  return (<div>
            <h1>Foo: {props.foo}</h1>
            <input onChange={props.updateFoo} value={props.foo} />
          </div>);
}

function objToValueProps(obj) {
  return {
    foo: obj.foo
  }
}

function objToFuncProps(obj) {
  return {
    updateFoo: function(e) {
      obj.setFoo(e.target.value);
    }
  }
}

function SmartModelView(props) {
  return connect(props.model, objToValueProps, objToFuncProps)(DumbModelView)
}

Now SmartModelView is a React component which takes in the model to render as a prop. You can use it like so:

function MainDiv() {
  return (<div>
            <h1> Your Model: </h1>
            <SmartModelView model={model} />
          </div>)
}

Using Stores

You may not want the user of your smart component to provide the model itself. Instead you can make it so that your smart component fetches the model out of a store:

// Song objects are Observable and contain the data we want to render.
// The SONG_STORE is a store for Songs. For this example, it has a byId
// method which returns the Song object for a given song id.

import SONG_STORE from './stores/song_store';

// ... define objToValueProps, objToFuncProps, and DumbSongView here

function SmartSongView(props) {
  const song = SONG_STORE.byId(props.id);
  return connect(song, objToValueProps, objToFuncProps)(DumbSongView)
}

Now you can use the SmartSongView without having an instance of the model, simply by providing the song's id.

function MainDiv() {
  return (<div>
            <h1> Now Playing: </h1>
            <SmartSongView id={512} />
          </div>)
}

Making Models Observable

You might be asking how you can take your existing models and make them Observable. Conveniently, react-observable-connect includes a helper Observable implementation that can help make any object observable.

For example, say you wanted to take the following model and make it Observable.

class Song {
  constructor(title, albumId) {
    this.title = title;
    this.albumId = albumId;
    this.playCount = 0;
    this.nowPlaying = false;
  }
  
  start() {
    this.nowPlaying = true;
    this.playCount += 1;
  }
  
  stop() {
    this.nowPlaying = false;
  }
}

For our purposes, for a model to be Observable it must contain a subscribe method which takes in a callback and returns an object containing an unsubscribe method. Anytime the model's state changes, the callback needs to be called.

Using composition, we will make our Song object contain an Observable object. We will also add a subscribe method which just proxies to the Observable object's subscribe method. Finally, whenever we update the state of the model, we will call the trigger method on the Observable object.

import {Observable} from 'react-observable-connect';

class Song {
  constructor(title, albumId) {
    this.title = title;
    this.albumId = albumId;
    this.playCount = 0;
    this.nowPlaying = false;
    this.observable = new Observable();
  }
  
  subscribe(func) {
    return this.observable.subscribe(func);
  }
  
  start() {
    this.nowPlaying = true;
    this.playCount += 1;
    this.observable.trigger();
  }
  
  stop() {
    this.nowPlaying = false;
    this.observable.trigger();
  }
}

Contributing

Feel free to send pull requests. Make sure that you have written test cases for your changes if possible.

License

react-observable-connect is MIT licensed.