0.1.1 • Published 4 years ago

@doublemx2/hooked-in v0.1.1

Weekly downloads
2
License
ISC
Repository
-
Last release
4 years ago

HookedIn

Library for running Hook-style data/control flows.

Like React Hooks, but without React.

Installation

npm install --save @doublemx2/hooked-in

Motivation

The data flow provided by React has been appealing to me (specifically React Hooks). In a nutshell, updates to specific state variables cause a 're-render'. This often allows complex logic flow to be localized to a single spot rather than strewn across various event handlers. At least, I feel that way.

This library gives the ability to use this style of data/control flow, but without the need to have to set-up React and ReactDOM. This does mean any actual 'rendering' that needs to be done, needs to be done by the user, usually in 'effects'.

Usage

const hookedIn = require('@doublemx2/hooked-in');
const { useState, useEffect } = hookedIn;

// assumes elements exist in DOM
const input = document.getElementById('input');
const textElement = document.getElementById('text');

hookedIn(() => {

  // state variable for the text
  const [text, setText] = useState('Initial Text');

  // update the contents of the textElement every time the text changes
  useEffect(() => {
    const textNode = document.createTextNode(text)
    textElement.appendChild(textNode)

    // clean-up function removes the previous content before the next render
    return () => {
      textElement.removeChild(textNode)
    }
  }, [text]) // dependency, re-runs everytime the text changes

  // add event listener to input
  useEffect(() => {
    function input_onChange (event) {
      setText(event.target.value)
    }
    input.addEventListener('change', input_onChange)

    // clean-up function removes the listener
    return () => {
      input.removeEventListener('change', input_onChange)
    }
  }, [setText])

  // bootstrap: set the value of the input to match text initially
  // only runs once, since there are no dependencies
  useEffect(() => {
    input.value = text
  })
})

The above example keeps the content of an element up-to-date with changes in the input. Of course, this is the standard HTML 'change' event that only runs on blur, so you would have to do more work for that.

API

This library is a work-in-progress and the interfaces may change version to version.

This documentation needs to be expanded on.

hookedIn(renderFunction)

Usage:

hookedIn(() => {
  useState(...);
  useEffect(...);
})

Creates a HookedIn instance. The renderFunction will be run immediately. It will be re-run every time a State hook updates (possibly in other cases).

If you're familiar Hooks, then you should know the Rules of Hooks. Basically, you need to make sure the same hooks get called in the exact same order on every run. Avoid calling hooks in loops and conditionals.

State Hook

Usage:

const { useState } = hookedIn

hookedIn(() =>
  const [value, setValue] = useState(initialValue)
))
  • initialValue: Any value or Function

    The initial value of the State hook. If a function is passed, it will be called on the first run to compute the initial value.

  • value: Any value

    The current value of the State hook.

  • setValue: function (update: any or Function) => void

    Updates the value of the State hook to update. If a function is passed, it will be passed the current value, return value will be used as next value. If the value changes under referential equality, a re-render will be performed.

Effect Hook

Usage:

const { useEffect } = hookedIn

hookedIn(() => {
  useEffect(() => {
    // effect code

    return () => {
      // clean-up code
    }
  })
}, deps)

Runs the effect code asynchrounously after the render function is run. Runs on first render. If deps are provider, will run every time a dep changes referentially.

deps is an array a values, these values should be used in the effect code.

effect code can optionally return a function. If provided, it will be called before the effect is re-run and when the HookedIn instance is stopped.

Ref Hook

const { useRef } = hookedIn

hookedIn(() => {
  const ref = useRef(initialValue)

  // use ref.current
}

Creates a ref object. The same object will be returned on every render. The render function can access ref.current to store a mutable value. initialValue will be used to initialize ref.current on first run. Mutating ref.current does not trigger a re-run.

createCustomHook

Allows for extended support for custom hooks in devtools. Work-in-progress.

Devtools

There is a Chrome Devtool extension in progress for this library.

Changes

  • v0.1.0 Initial Release: useState, useEffect, useRef, and createCustomHook