Compare commits

..

4 Commits

Author SHA1 Message Date
Brian Vaughn
5530c7565b RFC 6: createReactClass updates (#12036)
* Added UNSAFE_ methods to create-class HAS_MANY list
* Added warning for UNSAFE_componentWillRecieveProps misspelling
* Bumping create-react-class package version
* Added support for static getDerivedStateFromProps mixins
2018-01-19 15:13:26 -08:00
Jason Quense
4c75c5bf58 cherry pick radio input fix 2017-11-16 14:22:21 -05:00
Dan Abramov
571a9208d5 Tweak blog post to match others 2017-09-26 11:39:18 +01:00
Paul O’Shannessy
f1a8b33a02 Fix author in latest blog post (#10827)
Fix this so that @nhunzaker gets his name up there for real (will want to cherry-pick back to master but the blog post isn't there either so I'll let y'all handle that)
2017-09-26 11:33:31 +01:00
7 changed files with 137 additions and 21 deletions

View File

@@ -270,6 +270,27 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
*/
componentWillUnmount: 'DEFINE_MANY',
/**
* Replacement for (deprecated) `componentWillMount`.
*
* @optional
*/
UNSAFE_componentWillMount: 'DEFINE_MANY',
/**
* Replacement for (deprecated) `componentWillReceiveProps`.
*
* @optional
*/
UNSAFE_componentWillReceiveProps: 'DEFINE_MANY',
/**
* Replacement for (deprecated) `componentWillUpdate`.
*
* @optional
*/
UNSAFE_componentWillUpdate: 'DEFINE_MANY',
// ==== Advanced methods ====
/**
@@ -285,6 +306,23 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
updateComponent: 'OVERRIDE_BASE'
};
/**
* Similar to ReactClassInterface but for static methods.
*/
var ReactClassStaticInterface = {
/**
* This method is invoked after a component is instantiated and when it
* receives new props. Return an object to update state in response to
* prop changes. Return null to indicate no change to state.
*
* If an object is returned, its keys will be merged into the existing state.
*
* @return {object || null}
* @optional
*/
getDerivedStateFromProps: 'DEFINE_MANY_MERGED'
};
/**
* Mapping from class specification keys to special processing functions.
*
@@ -519,6 +557,7 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
if (!statics) {
return;
}
for (var name in statics) {
var property = statics[name];
if (!statics.hasOwnProperty(name)) {
@@ -535,14 +574,25 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
name
);
var isInherited = name in Constructor;
_invariant(
!isInherited,
'ReactClass: You are attempting to define ' +
'`%s` on your component more than once. This conflict may be ' +
'due to a mixin.',
name
);
var isAlreadyDefined = name in Constructor;
if (isAlreadyDefined) {
var specPolicy = ReactClassStaticInterface.hasOwnProperty(name)
? ReactClassStaticInterface[name]
: null;
_invariant(
specPolicy === 'DEFINE_MANY_MERGED',
'ReactClass: You are attempting to define ' +
'`%s` on your component more than once. This conflict may be ' +
'due to a mixin.',
name
);
Constructor[name] = createMergedResultFunction(Constructor[name], property);
return;
}
Constructor[name] = property;
}
}
@@ -852,6 +902,12 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?',
spec.displayName || 'A component'
);
warning(
!Constructor.prototype.UNSAFE_componentWillRecieveProps,
'%s has a method called UNSAFE_componentWillRecieveProps(). ' +
'Did you mean UNSAFE_componentWillReceiveProps()?',
spec.displayName || 'A component'
);
}
// Reduce time spent doing lookups by setting these on the prototype.

View File

@@ -1,6 +1,6 @@
{
"name": "create-react-class",
"version": "15.6.2",
"version": "15.6.3",
"description": "Legacy API for creating React components.",
"main": "index.js",
"license": "MIT",

View File

@@ -522,4 +522,55 @@ describe('ReactClass-spec', () => {
'to prevent memory leaks.'
);
});
it('should support getInitialState mixin', () => {
const Component = createReactClass({
mixins: [{
getInitialState: function(props) {
return {
foo: 'foo'
};
},
}],
getInitialState: function(props) {
return {
bar: 'bar'
};
},
render: function() {
return <div />;
}
});
const instance = renderIntoDocument(<Component />);
expect(instance.state.foo).toEqual('foo');
expect(instance.state.bar).toEqual('bar');
});
it('should merge return values for static getDerivedStateFromProps mixin', () => {
const Component = createReactClass({
mixins: [{
statics: {
getDerivedStateFromProps: function(props, prevState) {
return {
foo: 'foo'
};
}
},
}],
statics: {
getDerivedStateFromProps: function(props, prevState) {
return {
bar: 'bar'
};
}
},
render: function() {
return <div />;
}
});
const state = Component.getDerivedStateFromProps();
expect(state.foo).toEqual('foo');
expect(state.bar).toEqual('bar');
});
});

View File

@@ -49,6 +49,9 @@ LoukaN:
matthewjohnston4:
name: Matthew Johnston
url: https://github.com/matthewathome
nhunzaker:
name: Nathan Hunzaker
url: https://github.com/nhunzaker
petehunt:
name: Pete Hunt
url: https://twitter.com/floydophone

View File

@@ -48,13 +48,18 @@ We've also published version `15.6.2` of `react` and `react-dom` on npm, and the
## Changelog
## 15.6.2 (September 25th, 2017)
## 15.6.2 (September 25, 2017)
### All Packages
* Switch from BSD + Patents to MIT license
### React DOM
* Fix a bug where modifying document.documentMode would trigger IE detection in other browsers, breaking change events ([@aweary](https://github.com/aweary) in [#10032](https://github.com/facebook/react/pull/10032)
* CSS Columns are treated as unitless numbers ([@aweary](https://github.com/aweary) in [#10115](https://github.com/facebook/react/pull/10115)
* Fix bug in QtWebKit when wrapping synthetic events in proxies ([@walrusfruitcake](https://github.com/walrusfruitcake) in [#10115](https://github.com/facebook/react/pull/10011)
* Prevent event handlers from receiving extra argument (dev only) ([@aweary](https://github.com/aweary) in [#10115](https://github.com/facebook/react/pull/8363)
* Fix cases where onChange would not fire with defaultChecked on radio inputs ([@jquense](https://github.com/jquense) in [#10156](https://github.com/facebook/react/pull/10156))
* Add support for controlList attribute to DOM property whitelist ([@nhunzaker](https://github.com/nhunzaker) in [#9940](https://github.com/facebook/react/pull/9940))
* Fix a bug where modifying `document.documentMode` would trigger IE detection in other browsers, breaking change events. ([@aweary](https://github.com/aweary) in [#10032](https://github.com/facebook/react/pull/10032))
* CSS Columns are treated as unitless numbers. ([@aweary](https://github.com/aweary) in [#10115](https://github.com/facebook/react/pull/10115))
* Fix bug in QtWebKit when wrapping synthetic events in proxies. ([@walrusfruitcake](https://github.com/walrusfruitcake) in [#10115](https://github.com/facebook/react/pull/10011))
* Prevent event handlers from receiving extra argument in development. ([@aweary](https://github.com/aweary) in [#10115](https://github.com/facebook/react/pull/8363))
* Fix cases where `onChange` would not fire with `defaultChecked` on radio inputs. ([@jquense](https://github.com/jquense) in [#10156](https://github.com/facebook/react/pull/10156))
* Add support for `controlList` attribute to DOM property whitelist ([@nhunzaker](https://github.com/nhunzaker) in [#9940](https://github.com/facebook/react/pull/9940))
* Fix a bug where creating an element with a ref in a constructor did not throw an error in development. ([@iansu](https://github.com/iansu) in [#10025](https://github.com/facebook/react/pull/10025))

View File

@@ -13,7 +13,7 @@ var DOMPropertyOperations = require('DOMPropertyOperations');
var LinkedValueUtils = require('LinkedValueUtils');
var ReactDOMComponentTree = require('ReactDOMComponentTree');
var ReactUpdates = require('ReactUpdates');
var inputValueTracking = require('inputValueTracking');
var invariant = require('invariant');
var warning = require('warning');
@@ -348,6 +348,11 @@ function _handleChange(event) {
'ReactDOMInput: Mixing React and non-React radio inputs with the ' +
'same `name` is not supported.',
);
// We need update the tracked value on the named cousin since the value
// was changed but the input saw no event or value set
inputValueTracking.updateValueIfChanged(otherNode);
// If this is a controlled radio button group, forcing the input that
// was previously checked to update will cause it to be come re-checked
// as appropriate.

View File

@@ -907,10 +907,6 @@ ReactDOMComponent.Mixin = {
// happen after `_updateDOMProperties`. Otherwise HTML5 input validations
// raise warnings and prevent the new value from being assigned.
ReactDOMInput.updateWrapper(this);
// We also check that we haven't missed a value update, such as a
// Radio group shifting the checked value to another named radio input.
inputValueTracking.updateValueIfChanged(this);
break;
case 'textarea':
ReactDOMTextarea.updateWrapper(this);