Skip to content

Instantly share code, notes, and snippets.

@MrLeebo
Last active June 14, 2019 17:20
Show Gist options
  • Save MrLeebo/7e3025752206cd7c60f3c1fc43524b2b to your computer and use it in GitHub Desktop.
Save MrLeebo/7e3025752206cd7c60f3c1fc43524b2b to your computer and use it in GitHub Desktop.
const initialValues = {
username: "",
email: "",
password: "",
passwordConfirmation: "",
}
// always give your component a name, even if it is the default export,
// because it will appear in the Component Trace when there is a React error
export default function SignupForm() {
const [values, dispatch] = useReducer(formReducer, initialValues)
// dispatch is guaranteed to be persistent, so you can use it in another hook without
// needing to add it to the dependency array. this keeps your dependencies simple
const handleChange = useCallback(e => dispatch(change(e)), [])
const handleReset = useCallback(() => dispatch(reset()), [])
// you don't "need" useCallback for this simple case, you can also write:
// const handleChange = e => dispatch(change(e))
// or pass `dispatch` as a prop to a child component.
return (
<form>
<label>Username <input name="username" onChange={handleChange} value={values.username} /></label>
...
<button type="button" onClick={handleReset}>Reset</button>
<button>Submit</button>
</form>
)
}
// action creators give you a nice high-level summary of how your state can change
const change = e => ({ type: 'change', payload: { field: e.target.name, value: e.target.value } })
const reset = (payload=initialValues) => ({ type: 'reset', payload })
// finally the reducer contains the nitty gritty details
function formReducer(state, action) {
switch(action.type) {
case 'change': {
const { field, value } = action.payload
return { ...state, [field]: value }
}
case 'reset': {
return action.payload
}
default: {
throw new Error(`Unrecognized type: ${action.type}`)
}
}
}
@trevorglick
Copy link

Had to revise a couple things to adapt this to work.

For the dispatches:
const handleChange = e => { dispatch(change(e)); }; const handleReset = () => { dispatch(reset()); };

And for the inputs:
<label> Email <input type="email" name="email" onChange={e => handleChange(e)} value={values.email} /> </label>

Without the e => handleChange(e) it kept complaining about it not being a function and it being an object.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment