Created
January 9, 2023 20:56
-
-
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?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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