Skip to content

Instantly share code, notes, and snippets.

@ox
Created January 9, 2023 20:56
Show Gist options
  • Save ox/7bfa649c267ddbcd95527fb874243466 to your computer and use it in GitHub Desktop.
Save ox/7bfa649c267ddbcd95527fb874243466 to your computer and use it in GitHub Desktop.
Experimenting with using a reducer and a proxy to make controlled from inputs in React. A little messy, maybe too much?
import React, {useState, useReducer} from 'react';
const CHANGE_VALUE = 'change_value';
function formReducer(state, action) {
switch(action.type) {
case CHANGE_VALUE:
return {...state, [action.name]: action.value};
default:
return state;
}
}
function useControlledForm() {
const [form, formDispatch] = useReducer(formReducer, {});
function onChange(e) {
const name = e.target.name;
const value = e.target.value;
formDispatch({type: CHANGE_VALUE, name, value});
}
const handler = {
get(target, prop, receiver) {
if (!target.hasOwnProperty(prop)) {
target[prop] = '';
}
return Reflect.get(...arguments);
}
}
const formProxy = new Proxy(form, handler);
return [formProxy, onChange];
}
export function App(props) {
const [form, onChange] = useControlledForm();
function onSubmit(e) {
e.preventDefault();
console.log(form);
}
return (
<div className='App'>
<h1>Hello React.</h1>
<form onSubmit={onSubmit}>
<label>Name</label>
<input name="name" onChange={onChange} value={form.name} />
<label>Email</label>
<input name="email" onChange={onChange} value={form.email} />
<input type="submit" />
</form>
</div>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment