Skip to content

Commit

Permalink
Merge pull request #20 from reactjs/revert-breaking-change
Browse files Browse the repository at this point in the history
Revert accidental breaking change for 15.5
  • Loading branch information
gaearon committed Apr 11, 2017
2 parents 8b3d352 + fff750d commit ceb4a9e
Show file tree
Hide file tree
Showing 12 changed files with 2,961 additions and 525 deletions.
37 changes: 34 additions & 3 deletions README.md
Expand Up @@ -25,11 +25,42 @@ If you prefer a `<script>` tag, you can get it from `window.PropTypes` global:
<script src="https://unpkg.com/prop-types/prop-types.min.js"></script>
```

## Difference from `React.PropTypes`: Development and Production Versions
## Difference from `React.PropTypes`: Don’t Call Validator Functions

In production, **all validator functions are replaced with empty functions that throw an error**. This is done to optimize the bundle size. This is new behavior, and you will only encounter it when you migrate from `React.PropTypes` to the `prop-types` package. For the vast majority of components, this doesn’t matter, and if you didn’t see [this warning](https://facebook.github.io/react/warnings/dont-call-proptypes.html) in your components, your code is safe to migrate. This is not a breaking change in React because you are only opting into this change for a component by explicitly changing your imports to use `prop-types`.
When you migrate components to use the standalone `prop-types`, **all validator functions will start throwing an error if you call them directly**. This makes sure that nobody relies on them in production code, and it is safe to strip their implementations to optimize the bundle size.

Don’t call the validator functions manually in your code. React automatically calls `PropTypes` validators declared on your components in development version, and it won’t call them in production. **If you absolutely need to trigger the validation manually**, call `PropTypes.checkPropTypes(propTypes, props, location, componentName)`. Unlike the validators themselves, this function is safe to call in production, as it will be replaced by an empty function.
Code like this is still fine:

```js
MyComponent.propTypes = {
myProp: PropTypes.bool
};
```

However, code like this will not work with the `prop-types` package:

```js
// Will not work with `prop-types` package!
var errorOrNull = PropTypes.bool(42, 'myProp', 'MyComponent', 'prop');
```

It will throw an error:

```
Calling PropTypes validators directly is not supported by the `prop-types` package.
Use PropTypes.checkPropTypes() to call them.
```

This is new behavior, and you will only encounter it when you migrate from `React.PropTypes` to the `prop-types` package. For the vast majority of components, this doesn’t matter, and if you didn’t see [this warning](https://facebook.github.io/react/warnings/dont-call-proptypes.html) in your components, your code is safe to migrate. This is not a breaking change in React because you are only opting into this change for a component by explicitly changing your imports to use `prop-types`. If you temporarily need the old behavior, you can keep using `React.PropTypes` until React 16.

**If you absolutely need to trigger the validation manually**, call `PropTypes.checkPropTypes()`. Unlike the validators themselves, this function is safe to call in production, as it will be replaced by an empty function:

```js
// Works with standalone PropTypes
PropTypes.checkPropTypes(MyComponent.propTypes, props, 'prop', 'MyComponent');
```

**You might also see this error** if you’re calling a `PropTypes` validator from your own custom `PropTypes` validator. In this case, the fix is to make sure that you are passing *all* of the arguments to the inner function. There is a more in-depth explanation of how to fix it [on this page](https://facebook.github.io/react/warnings/dont-call-proptypes.html#fixing-the-false-positive-in-third-party-proptypes). Alternatively, you can temporarily keep using `React.PropTypes` until React 16, as it would still only warn in this case.

If you use a bundler like Browserify or Webpack, don’t forget to [follow these instructions](https://facebook.github.io/react/docs/installation.html#development-and-production-versions) to correctly bundle your application in development or production mode. Otherwise you’ll ship unnecessary code to your users.

Expand Down
Expand Up @@ -13,11 +13,13 @@

var React;
var PropTypes;
var checkPropTypes;

function resetWarningCache() {
jest.resetModules();
checkPropTypes = require('../checkPropTypes');

React = require('react');
// This is how React 15 imports `prop-types`.
PropTypes = require('../factory')(React.isValidElement);
}

function getPropTypeWarningMessage(propTypes, object, componentName) {
Expand All @@ -27,7 +29,8 @@ function getPropTypeWarningMessage(propTypes, object, componentName) {
console.error.calls.reset();
}
resetWarningCache();
checkPropTypes(propTypes, object, 'prop', 'testComponent');

PropTypes.checkPropTypes(propTypes, object, 'prop', 'testComponent');
const callCount = console.error.calls.count();
if (callCount > 1) {
throw new Error('Too many warnings.');
Expand Down Expand Up @@ -103,11 +106,8 @@ function expectWarningInDevelopment(declaration, value) {
console.error.calls.reset();
}

describe('ReactPropTypes', () => {
describe('PropTypesDevelopmentReact15', () => {
beforeEach(() => {
React = require('react');
PropTypes = require('../index');
checkPropTypes = PropTypes.checkPropTypes;
resetWarningCache();
});

Expand All @@ -120,7 +120,7 @@ describe('ReactPropTypes', () => {
},
};
const props = {foo: 'foo'};
const returnValue = checkPropTypes(
const returnValue = PropTypes.checkPropTypes(
propTypes,
props,
'prop',
Expand All @@ -139,7 +139,7 @@ describe('ReactPropTypes', () => {
},
};
const props = {foo: 'foo'};
const returnValue = checkPropTypes(
const returnValue = PropTypes.checkPropTypes(
propTypes,
props,
'prop',
Expand Down Expand Up @@ -839,9 +839,9 @@ describe('ReactPropTypes', () => {

it('should warn if called manually in development', () => {
spyOn(console, 'error');
expect(PropTypes.oneOf(['red', 'blue']), true);
expect(PropTypes.oneOf(['red', 'blue']), null);
expect(PropTypes.oneOf(['red', 'blue']), undefined);
expectWarningInDevelopment(PropTypes.oneOf(['red', 'blue']), true);
expectWarningInDevelopment(PropTypes.oneOf(['red', 'blue']), null);
expectWarningInDevelopment(PropTypes.oneOf(['red', 'blue']), undefined);
});
});

Expand Down

0 comments on commit ceb4a9e

Please sign in to comment.