Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

treble-hook

Package Overview
Dependencies
Maintainers
1
Versions
66
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

treble-hook

Get hooked on simple subscribe-and-publish in ReactJS.

  • 1.0.6
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
34
increased by3300%
Maintainers
1
Weekly downloads
 
Created
Source

treble-hook

Super easy way to get "hooked" on subscribe-and-publish in React with no dependencies and no cruft.


Installation

yarn add treble-hook

or

npm install --save treble-hook

Usage

Contrived sign-in component and a component that displays active user (signed-in user).

import React, { ChangeEvent, useState } from 'react'
import usePubSub from 'treble-hook'

const ACTIVE_USER_TOPIC = 'active-user'

function SignIn() {

  const [_, publishUser] = usePubSub<string>(ACTIVE_USER_TOPIC, '')
  const [entered, setEntered] = useState<string>('')

  return (
    <div>
      <input
        type='text'
        onChange={
          (evt: ChangeEvent<HTMLInputElement>) => {
            setEntered(evt.target.value)
          }
        }
      />
      <button onClick={ () => { publishUser(entered) }}>Sign-in</button>
    </div>
  )

}

function ActiveUser() {

  const [activeUser] = usePubSub<string>(
    ACTIVE_USER_TOPIC,
    'Anonymous'
  )

  return (
    <div>
      Active user: { activeUser }
    </div>
  )

}

TLDR; (jump right into it)

color-picker.tsx


import React from 'react'
import usePubSub from 'treble-hook'
import { BluePicker, GreenPicker, RedPicker } from './color-buttons'

const DEFAULT_COLOR_STATE = '[Pick a color by clicking a button]'

export default function ColorPicker() {

  const [
    color,
    publishColor,
    unsubscribeFromColor
  ] = usePubSub<string>('picked-color', DEFAULT_COLOR_STATE)

  return (
    <div style={{ fontSize: '16px'; }}>
      <span>Selected color:{ }</span>
      <span style={{ color: color; }}>{ color }</span>
    </div>
    <RedPicker /><BluePicker /><GreenPicker />
    <br/>
    <button onClick={ () => { publishColor(DEFAULT_COLOR_STATE) }}>
      Reset
    </button>
    <button onClick={ () => { unsubscribeFromColor() }}>
      Click to stop receiving color picks
    </button>
  )

}

color-buttons.tsx


import React from 'react'
import usePubSub from 'treble-hook'

const ColorButton = <{ cn: string }>({ cn }) => {

  const [_, publishColor] = usePubSub<string>('picked-color', '')

  return (
    <button
      style={{ color: cn }}
      onClick={ () => { publishColor(cn) }}
    >
      { cn.toUpperCase() }
    </button>
  )

}

export const RedButton = () => <ColorButton cn='red' />
export const GreenButton = () => <ColorButton cn='green' />
export const BlueButton = () => <ColorButton cn='blue' />

Current "state" of things

The advent of Hooks in React 16.8 introduced a paradigm shift in how state can be managed in applications built on top of React. Arguably, the defacto standard for managing application state prior to 16.8 was Redux. This worked great but it came with its own idiosyncrasies and a lot of boilerplate. There were/are great alternatives to Redux but each seems to have its own complexities and/or different mannerisms that can feel, at times, "too much".

While the hooks feature provides a much easier approach to state management, its focus is really at the component level and not necessarily at the application level. But if you think about it, this is a very good thing and makes perfect sense. After all, React is more a library and less a framework, so it should confine itself to the component landscape along with the composition idioms that breathe life into that landscape.

Sharing State

So what are we to do if there is application state that we really need to share across multiple components, especially deeply nested sub-components?

All of the pre-Hooks era options are certainly still available:

  • Passing state down via props (aka prop-passing hell)
  • Not-so-pretty code of render props
  • HoCs (powerful, but not suited for state management)
  • Context API (aka "global" application state)
  • Component composition (inversion-of-control)
  • Other state management libs (Redux, MobX, etc.)

But are any of these really well suited for a complext, real-world, single-page Web application? The authors of this library believe that the answer is no, with the possible exception of the Context API, but it just feels yucky to do this for application state that isn't pervasively global.

The authors of this library are responsible for a large, complex set of single-page applications, which demand (if we want to keep our sanity) that we keep all of our component/sub-component structure completely logical while being able to dispatch state and receive state without resorting to any of the aforementioned approaches.

To solve the problem, we wrote treble-hook, which very simply allows any component in an app to subscribe to state from anywhere in the tree and subsequently publish state at-will so that other components anywhere in the tree picks up those changes. Sounds like this would take a complicated library, right? Nope. Because treble-hook takes advantage of the power of hooks architecture, this functionality is possible via a library with zero hard dependencies and less than 3KB of code.

Caveat

Even though treble-hook was written in Typescript and thus is the preferred way to consume the library, types in Typescript are compile-time only, meaning they cannot be enforced at runtime without not-so-perfect third party libraries. As such, it's possible for one component to subscribe to a topic using a completely different type another subscribing component. If this were to happen, it would result in unexpected side-effects, for sure.

To mitigate this, it's a strongly suggested best practice to pre-define your state types with one or more enums and interfaces. This, of course, assumes you are writing your app in Typescript...and if you're not, you really should. But you don't have to. Regardless, like in Ghost Busters, you need to exercise extreme discipline and ensure that your proton packs don't cross streams. In other words, make sure that the data type published to a topic remains consistent throughout your application.

See the example code (coming soon) for a way to use an enum/interface to help enforce this policy to publish responsibly.

Documentation

Coming soon.

Authors

Awesome UX Dev team at Igneous Systems.

Issues

Coming soon.

Feaure Requests

Coming soon.

Liscense

MIT

Keywords

FAQs

Package last updated on 29 Jul 2019

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc