@doublemx2/hooked-in v0.1.1
HookedIn
Library for running Hook-style data/control flows.
Like React Hooks, but without React.
Installation
npm install --save @doublemx2/hooked-inMotivation
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 valueorFunctionThe initial value of the
Statehook. If a function is passed, it will be called on the first run to compute the initial value.value:Any valueThe current value of the
Statehook.setValue:function (update: any or Function) => voidUpdates the value of the
Statehook toupdate. If a function is passed, it will be passed the currentvalue, return value will be used as next value. If thevaluechanges 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, andcreateCustomHook