Created
January 16, 2016 23:22
-
-
Save tommikaikkonen/45d0d2ff2a5a383bb14d to your computer and use it in GitHub Desktop.
Using React PropTypes and defaultProps pattern with Redux-ORM models
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
import { PropTypes } from 'react'; | |
import { Model } from 'redux-orm'; | |
import getEnv from 'get-env'; | |
const env = getEnv(); | |
class ValidatingModel extends Model { | |
static _validateProps(props) { | |
if (typeof this.propTypes === 'object') { | |
forOwn(this.propTypes, (validator, key) => { | |
const result = validator(props, key, this.modelName); | |
if (result instanceof Error) { | |
throw result; | |
} | |
}); | |
} | |
} | |
static create(props) { | |
const defaults = this.hasOwnProperty('defaultProps') | |
? this.defaultProps | |
: {}; | |
const propsWithDefaults = Object.assign({}, defaults, props); | |
if (env !== 'prod') { | |
this._validateProps(propsWithDefaults); | |
} | |
return super.create(propsWithDefaults); | |
} | |
}; | |
// Use like this: | |
export class Person extends ValidatingModel { } | |
Person.modelName = 'Person'; | |
Person.propTypes = { | |
name: PropTypes.string.isRequired, | |
age: PropTypes.number.isRequired, | |
isFetching: PropTypes.bool.isRequired, | |
}; | |
Person.defaultProps = { | |
isFetching: false, | |
}; |
Yes, I have the same question: where does forOwn come from?
Also how about updating values through methods like .set(...)
, .update(...)
or .upsert(...)
. I'm guessing we'll need to override these methods too, right?
And what if we're updating like this:
Person.withId('some-id').name = 'updated name'
If I understand well, from react version 15+, we should use "prop-types" library instead of react, and thus manual validation is not required anymore :
https://www.npmjs.com/package/prop-types
But actually it doesn't work directly, so we have to use "PropTypes.checkPropTypes" from "prop-types".
I managed to make it work like this :
class ValidatingModel extends Model {
static _validateProps(props) {
if (typeof this.propTypes === 'object') {
const result = PropTypes.checkPropTypes(this.propTypes, props, 'prop', this.modelName);
if (result instanceof Error) {
throw result;
}
}
}
static create(props) {
if (typeof this.defaultProps === 'object') {
const propsWithDefaults = Object.assign({}, this.defaultProps, props);
this._validateProps(propsWithDefaults);
return super.create(propsWithDefaults);
}
this._validateProps(props);
return super.create(props);
}
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Where does
forOwn
come from, lodash?