Ms. Corlib
Ms. Corlib

Reputation: 5213

How can I declare a PropType corresponding to a nullable number?

I'm looking for a PropType that means

"this is required, and it will either be a number or be null"

In other words, what I have now is

PropTypes.number.isRequired

but that throws a warning if a null value gets passed in, yet I want null to be an acceptable value.

Upvotes: 96

Views: 91825

Answers (7)

hane Smitter
hane Smitter

Reputation: 870

This should be possible using:
Component.propTypes = {
  numberTypeProp: PropTypes.oneOfType([() => null, PropTypes.number])
}

This should mean that the prop(numberTypeProp) accepts a number or null value

Upvotes: 0

Nadiar Syaripul
Nadiar Syaripul

Reputation: 504

Yup just add

Component.propTypes = {
  numberAttribute: PropTypes.number
}

By default it will have undefined value. But you can chage default value to null or any number.

EventLeaderboardPage.defaultProps = {
  numberAttribute: null
}

Upvotes: 0

Ivan Gabriele
Ivan Gabriele

Reputation: 6900

To help with this quite common issue, I created a clean and fully-typed wrapper called better-prop-types:

import BetterPropTypes from 'better-prop-types'

// ...

MyComponent.propTypes = {
  aProp: BetterPropTypes.string.isRequiredButNullable,
}

Upvotes: 3

ctrlplusb
ctrlplusb

Reputation: 13147

Just use:

PropTypes.number

By default all prop types aren't required (i.e. allow null or undefined) unless you pop a .isRequired on the end of them.

You can see the full docs for proptypes here:

Upvotes: 63

Eduard Fedoruk
Eduard Fedoruk

Reputation: 350

You simply could use:

PropTypes.number

and in defaultProps:

yourPropName: null

Upvotes: 34

Adam
Adam

Reputation: 37

import propTypes from 'prop-types';

const nullable = propType => (props, propName, ...rest) =>
  props[propName] === null ? null : propType(props, propName, ...rest);

const testMe = {
  a: 'string',
  b: 420,
  c: null,
  d: undefined,
  e: undefined
};

const testSchema = {
  a: nullable(propTypes.string.isRequired),
  b: nullable(propTypes.string.isRequired),
  c: nullable(propTypes.number.isRequired),
  d: nullable(propTypes.bool.isRequired),
  e: nullable(propTypes.number)
};

propTypes.checkPropTypes(testSchema, testMe, 'prop', 'testMe');
// Warning: Failed prop type: Invalid prop `b` of type `number` supplied to `testMe`, expected `string`.
// Warning: Failed prop type: The prop `d` is marked as required in `testMe`, but its value is `undefined`.

Upvotes: 2

Lu Tran
Lu Tran

Reputation: 401

Currently prop-types library don't allow this. The way i get around this is using a custom validation function

MyComponent.propTypes = {
  nullableArray: function(props, propName, componentName) {
    const { propName: data } = props;

    if (data === undefined) {
      return new Error(`Undefined ${propName} is not allowed`);
    }

    if (data !== null) {
      return; //this is allow when data is loading
    }

    if (!_.isArray(data)) {
      return new Error(`${propName} must be an array`);
    }
  }
};

You can make another step further to create a high order function to generate the validation function. this should get you started

generateRequiredOrNullValidationFunction = expectedType => {
  if (expectedType !== "array") {
    return Error(`Unexpected ${expectedType}`);
  }

  return function(props, propName, componentName) {
    const { [propName]: data } = props;

    if (data === undefined) {
      return new Error(`Undefined ${propName} is not allowed`);
    }

    if (data !== null) {
      return; //this is allow when data is loading
    }

    if (expectedType === "array" && !_.isArray(data)) {
      return new Error(`${propName} must be an array`);
    }
  };
};

In this snippet, expectedType is a enumeration such as bool , array, number ...

Upvotes: 8

Related Questions