Skip to content

Instantly share code, notes, and snippets.

@ironboy
Created December 28, 2022 15:57
Show Gist options
  • Save ironboy/7ab70c6ab322bd7d0dcc923d3b732f3d to your computer and use it in GitHub Desktop.
Save ironboy/7ab70c6ab322bd7d0dcc923d3b732f3d to your computer and use it in GitHub Desktop.
Simplify context, states and form handling in React
// Simplify states, contexts and binding to forms
// ironboy 2022
import { useState, useDebugValue } from 'react';
const savedStates = {};
export function useStates(initObj, contextName) {
typeof initObj === 'string'
&& ([initObj, contextName] = [contextName, initObj]);
useDebugValue(contextName || 'local state');
const [state, setState] = initObj ?
useState(initObj) : savedStates[contextName];
savedStates[contextName] = [state, setState];
const proxyHandler = {
get(obj, key) {
return {
_isProxy: true,
bind: (...args) => bind(makeProxy(obj), ...args)
}[key]
|| makeProxy(obj[key]);
},
set(obj, key, val) {
obj[key] = val;
setState({ ...state });
return true;
},
deleteProperty(obj, key) {
delete obj[key];
setState({ ...state });
return true;
}
};
const makeProxy = x => x instanceof Object && !x._isProxy ?
new Proxy(x, proxyHandler) : x;
return makeProxy(state);
}
function bind(obj, name, value = obj[name], altValue) {
return {
name,
value,
checked: obj[name] === value,
onChange: ({ target: t }) =>
t.type === 'checkbox' ?
obj[name] = t.checked ? value : altValue :
obj[name] = t.type === 'number' ?
(isNaN(+t.value) ? t.value : +t.value) : t.value
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment