Skip to content

Instantly share code, notes, and snippets.

@tommikaikkonen
Created January 16, 2016 23:22
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tommikaikkonen/45d0d2ff2a5a383bb14d to your computer and use it in GitHub Desktop.
Save tommikaikkonen/45d0d2ff2a5a383bb14d to your computer and use it in GitHub Desktop.
Using React PropTypes and defaultProps pattern with Redux-ORM models
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,
};
@shawnlauzon
Copy link

Where does forOwn come from, lodash?

@Aerendir
Copy link

Aerendir commented Apr 7, 2018

Yes, I have the same question: where does forOwn come from?

@irtazabbas
Copy link

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'

@neo7-studio-web
Copy link

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

@neo7-studio-web
Copy link

neo7-studio-web commented Sep 17, 2018

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