Last active
June 14, 2019 17:20
-
-
Save MrLeebo/7e3025752206cd7c60f3c1fc43524b2b to your computer and use it in GitHub Desktop.
This file contains 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
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}`) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.