Last active
May 9, 2017 02:04
-
-
Save granmoe/e344fe1f89ff171d94cfb71674090477 to your computer and use it in GitHub Desktop.
Simple form validation through a Higher Order Component. Same as the other ones I made, except this caches functions so shouldComponentUpdate of the child doesn't always return true.
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 from 'react' | |
export default options => { | |
return WrappedComponent => class FormValidation extends React.Component { | |
constructor () { | |
super() | |
this.validate = options.validate | |
this.cachedFunctions = { onChange: {}, onBlur: {} } | |
this.state = options.fields.reduce((result, field) => { | |
result.fields.push(field) | |
result.errors[field] = '' | |
result.values[field] = '' | |
result.touched[field] = false | |
return result | |
}, { fields: [], errors: {}, values: {}, touched: {} }) | |
} | |
onBlur (field, e) { | |
const touched = this.state.touched | |
touched[field] = true | |
this.setState({ touched }) | |
this.runValidate(field, e.target.value) | |
} | |
onChange (field, e) { | |
this.runValidate(field, e.target.value) | |
} | |
runValidate = (field, value) => { | |
const values = this.state.values | |
values[field] = value | |
this.setState(this.validate(values)) // TODO: Only need to validate the value that changed here | |
} | |
getCachedFunction (functionName, fieldName) { | |
if (!this.cachedFunctions[functionName][fieldName]) { | |
this.cachedFunctions[functionName][fieldName] = this[functionName]['bind'](this, fieldName) | |
} | |
return this.cachedFunctions[functionName][fieldName] | |
} | |
mapStateToChildProps = (state) => { | |
return state.fields.reduce((result, field) => { | |
result[field] = { | |
value: state.values[field], | |
error: state.errors[field], | |
touched: state.touched[field], | |
onChange: this.getCachedFunction('onChange', field), | |
onBlur: this.getCachedFunction('onBlur', field), | |
} | |
return result | |
}, {}) | |
} | |
render () { | |
return <WrappedComponent {...this.props} {...this.mapStateChildToProps(this.state)} isValid={this.isValid(this.state)} /> | |
} | |
isValid (state) { | |
return state.fields.reduce((previous, current) => previous && (!!state.values[current] && !state.errors[current]), true) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@TimothyJohnK Anytime, just remind me next time we hang out :-)