Use specific method names in error messages
Dan Abramov committed
Mar 21, 2016 at 21:40 UTC
ebe51284896981142af5b8b1509df17419f2b644
4 files changed
+88
-31
src/isomorphic/classic/class/ReactClass.js
+1
-1
@@ -710,7 +710,7 @@ var ReactClassMixin = {
710
replaceState: function(newState, callback) {
711
this.updater.enqueueReplaceState(this, newState);
712
if (callback) {
713
- this.updater.enqueueCallback(this, callback);
713
+ this.updater.enqueueCallback(this, callback, 'replaceState');
714
}
715
},
716
src/isomorphic/modern/class/ReactComponent.js
+2
-2
@@ -76,7 +76,7 @@ ReactComponent.prototype.setState = function(partialState, callback) {
76
}
77
this.updater.enqueueSetState(this, partialState);
78
if (callback) {
79
- this.updater.enqueueCallback(this, callback);
79
+ this.updater.enqueueCallback(this, callback, 'setState');
80
}
81
};
82
@@ -97,7 +97,7 @@ ReactComponent.prototype.setState = function(partialState, callback) {
97
ReactComponent.prototype.forceUpdate = function(callback) {
98
this.updater.enqueueForceUpdate(this);
99
if (callback) {
100
- this.updater.enqueueCallback(this, callback);
100
+ this.updater.enqueueCallback(this, callback, 'forceUpdate');
101
}
102
};
103
src/renderers/shared/reconciler/ReactUpdateQueue.js
+5
-4
@@ -116,14 +116,15 @@ var ReactUpdateQueue = {
116
*
117
* @param {ReactClass} publicInstance The instance to use as `this` context.
118
* @param {?function} callback Called after state is updated.
119
+ * @param {string} callerName Name of the calling function in the public API.
120
* @internal
121
*/
121
- enqueueCallback: function(publicInstance, callback) {
122
+ enqueueCallback: function(publicInstance, callback, callerName) {
123
invariant(
124
typeof callback === 'function',
124
- 'enqueueCallback(...): You called `setState`, `replaceState`, or ' +
125
- '`forceUpdate` with the last argument of type %s. When specified, ' +
126
- 'their last `callback` argument is expected to be a function.',
125
+ 'enqueueCallback(...): You called `%s` with the last argument of type ' +
126
+ '%s. When specified, its last `callback` argument must be a function.',
127
+ callerName,
128
formatUnexpectedArgument(callback)
129
);
130
var internalInstance = getInternalInstanceReadyForUpdate(publicInstance);
src/renderers/shared/reconciler/__tests__/ReactUpdates-test.js
+80
-24
@@ -938,7 +938,7 @@ describe('ReactUpdates', function() {
938
}
939
});
940
941
- it('throws when the update callback is not a function', function() {
941
+ it('throws in setState if the update callback is not a function', function() {
942
function Foo() {
943
this.a = 1;
944
this.b = 2;
@@ -953,28 +953,84 @@ describe('ReactUpdates', function() {
953
});
954
var component = ReactTestUtils.renderIntoDocument(<A />);
955
956
- var stringMessage =
957
- 'enqueueCallback(...): You called `setState`, `replaceState`, or '+
958
- '`forceUpdate` with the last argument of type string. When specified, ' +
959
- 'their last `callback` argument is expected to be a function.';
960
- expect(() => component.setState({}, 'no')).toThrow(stringMessage);
961
- expect(() => component.replaceState({}, 'no')).toThrow(stringMessage);
962
- expect(() => component.forceUpdate('no')).toThrow(stringMessage);
963
-
964
- var objectMessage =
965
- 'enqueueCallback(...): You called `setState`, `replaceState`, or '+
966
- '`forceUpdate` with the last argument of type Object. When specified, ' +
967
- 'their last `callback` argument is expected to be a function.';
968
- expect(() => component.setState({}, {})).toThrow(objectMessage);
969
- expect(() => component.replaceState({}, {})).toThrow(objectMessage);
970
- expect(() => component.forceUpdate({})).toThrow(objectMessage);
971
-
972
- var fooMessage =
973
- 'enqueueCallback(...): You called `setState`, `replaceState`, or '+
974
- '`forceUpdate` with the last argument of type Foo (keys: a, b). When ' +
975
- 'specified, their last `callback` argument is expected to be a function.';
976
- expect(() => component.setState({}, new Foo())).toThrow(fooMessage);
977
- expect(() => component.replaceState({}, new Foo())).toThrow(fooMessage);
978
- expect(() => component.forceUpdate(new Foo())).toThrow(fooMessage);
956
+ expect(() => component.setState({}, 'no')).toThrow(
957
+ 'enqueueCallback(...): You called `setState` with the last argument of ' +
958
+ 'type string. When specified, its last `callback` argument must be a ' +
959
+ 'function.'
960
+ );
961
+ expect(() => component.setState({}, {})).toThrow(
962
+ 'enqueueCallback(...): You called `setState` with the last argument of ' +
963
+ 'type Object. When specified, its last `callback` argument must be a ' +
964
+ 'function.'
965
+ );
966
+ expect(() => component.setState({}, new Foo())).toThrow(
967
+ 'enqueueCallback(...): You called `setState` with the last argument of ' +
968
+ 'type Foo (keys: a, b). When specified, its last `callback` argument ' +
969
+ 'must be a function.'
970
+ );
971
+ });
972
+
973
+ it('throws in replaceState if the update callback is not a function', function() {
974
+ function Foo() {
975
+ this.a = 1;
976
+ this.b = 2;
977
+ }
978
+ var A = React.createClass({
979
+ getInitialState: function() {
980
+ return {};
981
+ },
982
+ render: function() {
983
+ return <div />;
984
+ },
985
+ });
986
+ var component = ReactTestUtils.renderIntoDocument(<A />);
987
+
988
+ expect(() => component.replaceState({}, 'no')).toThrow(
989
+ 'enqueueCallback(...): You called `replaceState` with the last ' +
990
+ 'argument of type string. When specified, its last `callback` argument ' +
991
+ 'must be a function.'
992
+ );
993
+ expect(() => component.replaceState({}, {})).toThrow(
994
+ 'enqueueCallback(...): You called `replaceState` with the last ' +
995
+ 'argument of type Object. When specified, its last `callback` argument ' +
996
+ 'must be a function.'
997
+ );
998
+ expect(() => component.replaceState({}, new Foo())).toThrow(
999
+ 'enqueueCallback(...): You called `replaceState` with the last ' +
1000
+ 'argument of type Foo (keys: a, b). When specified, its last ' +
1001
+ '`callback` argument must be a function.'
1002
+ );
1003
+ });
1004
+
1005
+ it('throws in forceUpdate if the update callback is not a function', function() {
1006
+ function Foo() {
1007
+ this.a = 1;
1008
+ this.b = 2;
1009
+ }
1010
+ var A = React.createClass({
1011
+ getInitialState: function() {
1012
+ return {};
1013
+ },
1014
+ render: function() {
1015
+ return <div />;
1016
+ },
1017
+ });
1018
+ var component = ReactTestUtils.renderIntoDocument(<A />);
1019
+
1020
+ expect(() => component.forceUpdate('no')).toThrow(
1021
+ 'enqueueCallback(...): You called `forceUpdate` with the last ' +
1022
+ 'argument of type string. When specified, its last `callback` argument ' +
1023
+ 'must be a function.'
1024
+ );
1025
+ expect(() => component.forceUpdate({})).toThrow(
1026
+ 'enqueueCallback(...): You called `forceUpdate` with the last ' +
1027
+ 'argument of type Object. When specified, its last `callback` argument ' +
1028
+ 'must be a function.'
1029
+ );
1030
+ expect(() => component.forceUpdate(new Foo())).toThrow(
1031
+ 'enqueueCallback(...): You called `forceUpdate` with the last ' +
1032
+ 'argument of type Foo (keys: a, b). When specified, its last ' +
1033
+ '`callback` argument must be a function.'
1034
+ );
1035
});
1036
});