mirror of
https://github.com/zebrajr/react.git
synced 2025-12-06 12:20:20 +01:00
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
This commit is contained in:
parent
4c75c5bf58
commit
5530c7565b
|
|
@ -270,6 +270,27 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
|
||||||
*/
|
*/
|
||||||
componentWillUnmount: 'DEFINE_MANY',
|
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 ====
|
// ==== Advanced methods ====
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -285,6 +306,23 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
|
||||||
updateComponent: 'OVERRIDE_BASE'
|
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.
|
* Mapping from class specification keys to special processing functions.
|
||||||
*
|
*
|
||||||
|
|
@ -519,6 +557,7 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
|
||||||
if (!statics) {
|
if (!statics) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var name in statics) {
|
for (var name in statics) {
|
||||||
var property = statics[name];
|
var property = statics[name];
|
||||||
if (!statics.hasOwnProperty(name)) {
|
if (!statics.hasOwnProperty(name)) {
|
||||||
|
|
@ -535,14 +574,25 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
|
||||||
name
|
name
|
||||||
);
|
);
|
||||||
|
|
||||||
var isInherited = name in Constructor;
|
var isAlreadyDefined = name in Constructor;
|
||||||
_invariant(
|
if (isAlreadyDefined) {
|
||||||
!isInherited,
|
var specPolicy = ReactClassStaticInterface.hasOwnProperty(name)
|
||||||
'ReactClass: You are attempting to define ' +
|
? ReactClassStaticInterface[name]
|
||||||
'`%s` on your component more than once. This conflict may be ' +
|
: null;
|
||||||
'due to a mixin.',
|
|
||||||
name
|
_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;
|
Constructor[name] = property;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -852,6 +902,12 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
|
||||||
'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?',
|
'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?',
|
||||||
spec.displayName || 'A component'
|
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.
|
// Reduce time spent doing lookups by setting these on the prototype.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "create-react-class",
|
"name": "create-react-class",
|
||||||
"version": "15.6.2",
|
"version": "15.6.3",
|
||||||
"description": "Legacy API for creating React components.",
|
"description": "Legacy API for creating React components.",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|
|
||||||
|
|
@ -522,4 +522,55 @@ describe('ReactClass-spec', () => {
|
||||||
'to prevent memory leaks.'
|
'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');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user